package org.linlinjava.litemall.wx.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.annotations.VisibleForTesting;
import lombok.SneakyThrows;
import org.apache.commons.lang3.ObjectUtils;
import org.linlinjava.litemall.core.config.DynamicTimeZoneConfiguration;
import org.linlinjava.litemall.core.system.SystemConfig;
import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.util.ResponseUtil.Response;
import org.linlinjava.litemall.db.beans.Constants;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.dto.AdminShopSpecialDateDTO;
import org.linlinjava.litemall.db.dto.WxMemberSourceDTO;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.wx.dto.CartDTO;
import org.linlinjava.litemall.wx.util.WxResponseEnum;
import org.linlinjava.litemall.wx.vo.*;
import org.linlinjava.litemall.wx.vo.cart.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.*;
import java.util.*;
import java.util.stream.Collectors;

import static org.linlinjava.litemall.wx.util.WxResponseCode.*;

/**
 * @author ：stephen
 * @date ：Created in 2020/6/9 11:35
 * @description：购物车
 */
@Service
@Transactional
public class WxCartService {

    @Autowired
    private LitemallCartService cartService;

    @Autowired
    private LumiereCartService lumiereCartService;

    @Autowired
    private LitemallGoodsService goodsService;
    @Autowired
    private LitemallCategoryService litemallCategoryService;
    @Autowired
    private LitemallGoodsProductService productService;
    @Autowired
    private LitemallAddressService addressService;
    @Autowired
    private LitemallCouponUserService couponUserService;
    @Autowired
    private LitemallGoodsSpecificationService specificationService;
    @Autowired
    private CouponVerifyService couponVerifyService;
    @Autowired
    private LitemallShopService litemallShopService;
    @Autowired
    private LitemallTaxService litemallTaxService;
    @Autowired
    private LitemallShopRegionService litemallShopRegionService;
    @Autowired
    private LitemallGoodsAccessoryService litemallGoodsAccessoryService;
    @Autowired
    private LitemallCartGoodsAccessoryService litemallCartGoodsAccessoryService;
    @Autowired
    private LitemallShopMerchandiseService litemallShopMerchandiseService;
    @Autowired
    private LitemallGoodsProductService litemallGoodsProductService;
    @Autowired
    private LitemallGoodsSpecificationMerchandiseService goodsSpecificationMerchandiseService;
    @Autowired
    private LumiereCartGoodsFormulaSpecificationsDataProportioningService lumiereCartGoodsFormulaSpecificationsDataProportioningService;
    @Autowired
    private LumiereFormulaSpecificationsDataProportioningService lumiereFormulaSpecificationsDataProportioningService;
    @Autowired
    private LumiereFormulaMaterialService lumiereFormulaMaterialService;
    @Autowired
    private LitemallShopRegionService shopRegionService;
    @Autowired
    private LitemallRegionService regionService;
    @Autowired
    private LitemallGoodsRegionService goodsRegionService;
    @Autowired
    private LitemallCartGoodsPropertyService litemallCartGoodsPropertyService;

    @Autowired
    private LumiereCartGoodsPropertyService lumiereCartGoodsPropertyService;

    @Autowired
    private LitemallGoodsPropertyService litemallGoodsPropertyService;

    @Autowired
    private LumierePayMemberUserService payMemberUserService;
    @Autowired
    private LumierePayMemberService lumierePayMemberService;

    @Autowired
    private LumierePackageService lumierePackageService;

    @Autowired
    private LumiereFormulaSpecificationsService lumiereFormulaSpecificationsService;

    @Autowired
    private LumiereCartPackageService lumiereCartPackageService;

    @Autowired
    private LitemallCouponService litemallCouponService;

    /**
     * wx商品服务
     */
    @Autowired
    private WxGoodsService wxGoodsService;

    @Autowired
    private LitemallRegionService litemallRegionService;

    @Autowired
    private LitemallCartService litemallCartService;

    @Autowired
    private LumiereCouponUserService lumiereCouponUserService;
    
    @Autowired
    private LumiereCouponStrategyService lumiereCouponStrategyService;
    @Autowired
    private LumiereCouponService lumiereCouponService;

    @Autowired
    private LumiereCartGoodsService lumiereCartGoodsService;

    //各地时差
    @Value("${sys.difference}")
    private Long difference;

    private DynamicTimeZoneConfiguration dynamicTimeZoneConfiguration = new DynamicTimeZoneConfiguration();

    public Response list(Integer userId, Integer shopId) {
        List<LumiereCart> cartList = lumiereCartService.list(Wrappers.lambdaQuery(LumiereCart.class)
                //.eq(LumiereCart::getShopId,shopId)
                .eq(LumiereCart::getUserId,userId)
                .orderByDesc(LumiereCart::getAddTime));

        List<CartListRespVO> cartListRespVOS = new ArrayList<>();
        for (LumiereCart cart : cartList) {
            CartListRespVO cartRespVO = new CartListRespVO();
            cartRespVO.setId(cart.getId());
            cartRespVO.setPrice(cart.getPrice());
            cartRespVO.setType(cart.getType());

            if(cart.getType()==0){
                CartListRespVO.CartGoodsRespVO cartGoodsRespVO = new CartListRespVO.CartGoodsRespVO();
                LumiereCartGoods cartGoods = lumiereCartGoodsService.getById(cart.getCartGoodsId());
                LitemallGoods goods = goodsService.findById(cartGoods.getGoodsId());
                //规格
                LumiereFormulaSpecifications formulaSpecifications = lumiereFormulaSpecificationsService.getById(cartGoods.getSpecificationId());

                cartGoodsRespVO.setId(cartGoods.getId());
                cartGoodsRespVO.setNumber(cartGoods.getNumber());
                cartGoodsRespVO.setName(goods.getName());
                cartGoodsRespVO.setPicUrl(goods.getPicUrl());
                cartGoodsRespVO.setSpecificationsName(formulaSpecifications.getSpecificationsName());

                //属性
                List<LumiereCartGoodsProperty> cartGoodsProperties = lumiereCartGoodsPropertyService.list(Wrappers.lambdaQuery(LumiereCartGoodsProperty.class)
                        .eq(LumiereCartGoodsProperty::getCartGoodsId, cart.getCartGoodsId()));
                cartGoodsRespVO.setGoodsProperties(cartGoodsProperties);

                List<LumiereCartGoodsFormulaSpecificationsDataProportioning> cartGoodsFormulaSpecificationsDataProportionings = lumiereCartGoodsFormulaSpecificationsDataProportioningService.list(Wrappers.lambdaQuery(LumiereCartGoodsFormulaSpecificationsDataProportioning.class)
                        .eq(LumiereCartGoodsFormulaSpecificationsDataProportioning::getCartGoodsId, cartGoods.getId()));
                List<CartListRespVO.CartListGoodsFormulaSpecificationsDataProportioningRespVO> cartListGoodsFormulaSpecificationsDataProportioningList = new ArrayList<>();
                for (LumiereCartGoodsFormulaSpecificationsDataProportioning cartGoodsFormulaSpecificationsDataProportioning : cartGoodsFormulaSpecificationsDataProportionings) {

                    LumiereFormulaSpecificationsDataProportioning proportioningServiceById = lumiereFormulaSpecificationsDataProportioningService.getById(cartGoodsFormulaSpecificationsDataProportioning.getFormulaSpecificationsDataProportioningId());
                    LumiereFormulaMaterial formulaMaterial = lumiereFormulaMaterialService.getById(proportioningServiceById.getFormulaMaterialId());

                    CartListRespVO.CartListGoodsFormulaSpecificationsDataProportioningRespVO cartListGoodsFormulaSpecificationsDataProportioningRespVO = new CartListRespVO.CartListGoodsFormulaSpecificationsDataProportioningRespVO();
                    cartListGoodsFormulaSpecificationsDataProportioningRespVO.setId(cartGoodsFormulaSpecificationsDataProportioning.getId());
                    cartListGoodsFormulaSpecificationsDataProportioningRespVO.setQuantity(cartGoodsFormulaSpecificationsDataProportioning.getQuantity());
                    cartListGoodsFormulaSpecificationsDataProportioningRespVO.setPrice(cartGoodsFormulaSpecificationsDataProportioning.getPrice());
                    cartListGoodsFormulaSpecificationsDataProportioningRespVO.setMaterialName(formulaMaterial.getMaterialName());
                    cartListGoodsFormulaSpecificationsDataProportioningRespVO.setMakeUnit(cartGoodsFormulaSpecificationsDataProportioning.getMakeUnit());
                    cartListGoodsFormulaSpecificationsDataProportioningList.add(cartListGoodsFormulaSpecificationsDataProportioningRespVO);
                }
                cartGoodsRespVO.setSpecificationsDataProportioningList(cartListGoodsFormulaSpecificationsDataProportioningList);
                cartRespVO.setCartGoods(cartGoodsRespVO);
            }else {
                CartListRespVO.CartPackageRespVO cartPackageRespVO = new CartListRespVO.CartPackageRespVO();
                LumiereCartPackage cartPackage = lumiereCartPackageService.getById(cart.getCartPackageId());
                LumierePackage lumierePackage = lumierePackageService.getById(cartPackage.getPackageId());

                cartPackageRespVO.setId(cartPackage.getId());
                cartPackageRespVO.setNumber(cartPackage.getNumber());
                cartPackageRespVO.setPrice(cartPackage.getPrice());
                cartPackageRespVO.setPicUrl(lumierePackage.getPackageImg());
                cartPackageRespVO.setName(lumierePackage.getPackageName());

                List<CartListRespVO.CartGoodsRespVO> cartListPackageGoodsList = new ArrayList<>();
                for (LumiereCartGoods cartGoods : lumiereCartGoodsService.listByIds(cartPackage.getCartGoodsIds())) {
                    CartListRespVO.CartGoodsRespVO cartGoodsRespVO = new CartListRespVO.CartGoodsRespVO();
                    LitemallGoods goods = goodsService.findById(cartGoods.getGoodsId());
                    //规格
                    LumiereFormulaSpecifications formulaSpecifications = lumiereFormulaSpecificationsService.getById(cartGoods.getSpecificationId());

                    cartGoodsRespVO.setId(cartGoods.getId());
                    cartGoodsRespVO.setNumber(cartGoods.getNumber());
                    cartGoodsRespVO.setName(goods.getName());
                    cartGoodsRespVO.setPicUrl(goods.getPicUrl());
                    cartGoodsRespVO.setSpecificationsName(formulaSpecifications.getSpecificationsName());

                    //属性
                    List<LumiereCartGoodsProperty> cartGoodsProperties = lumiereCartGoodsPropertyService.list(Wrappers.lambdaQuery(LumiereCartGoodsProperty.class)
                            .eq(LumiereCartGoodsProperty::getCartGoodsId, cartGoods.getId()));
                    cartGoodsRespVO.setGoodsProperties(cartGoodsProperties);

                    List<LumiereCartGoodsFormulaSpecificationsDataProportioning> cartGoodsFormulaSpecificationsDataProportionings = lumiereCartGoodsFormulaSpecificationsDataProportioningService.list(Wrappers.lambdaQuery(LumiereCartGoodsFormulaSpecificationsDataProportioning.class)
                            .eq(LumiereCartGoodsFormulaSpecificationsDataProportioning::getCartGoodsId, cartGoods.getId()));
                    List<CartListRespVO.CartListGoodsFormulaSpecificationsDataProportioningRespVO> cartListGoodsFormulaSpecificationsDataProportioningList = new ArrayList<>();
                    for (LumiereCartGoodsFormulaSpecificationsDataProportioning cartGoodsFormulaSpecificationsDataProportioning : cartGoodsFormulaSpecificationsDataProportionings) {

                        LumiereFormulaSpecificationsDataProportioning proportioningServiceById = lumiereFormulaSpecificationsDataProportioningService.getById(cartGoodsFormulaSpecificationsDataProportioning.getFormulaSpecificationsDataProportioningId());
                        LumiereFormulaMaterial formulaMaterial = lumiereFormulaMaterialService.getById(proportioningServiceById.getFormulaMaterialId());

                        CartListRespVO.CartListGoodsFormulaSpecificationsDataProportioningRespVO cartListGoodsFormulaSpecificationsDataProportioningRespVO = new CartListRespVO.CartListGoodsFormulaSpecificationsDataProportioningRespVO();
                        cartListGoodsFormulaSpecificationsDataProportioningRespVO.setId(cartGoodsFormulaSpecificationsDataProportioning.getId());
                        cartListGoodsFormulaSpecificationsDataProportioningRespVO.setQuantity(cartGoodsFormulaSpecificationsDataProportioning.getQuantity());
                        cartListGoodsFormulaSpecificationsDataProportioningRespVO.setPrice(cartGoodsFormulaSpecificationsDataProportioning.getPrice());
                        cartListGoodsFormulaSpecificationsDataProportioningRespVO.setMaterialName(formulaMaterial.getMaterialName());
                        cartListGoodsFormulaSpecificationsDataProportioningRespVO.setMakeUnit(cartGoodsFormulaSpecificationsDataProportioning.getMakeUnit());
                        cartListGoodsFormulaSpecificationsDataProportioningList.add(cartListGoodsFormulaSpecificationsDataProportioningRespVO);
                    }
                    cartGoodsRespVO.setSpecificationsDataProportioningList(cartListGoodsFormulaSpecificationsDataProportioningList);

                    cartListPackageGoodsList.add(cartGoodsRespVO);
                }

                cartPackageRespVO.setCartListGoodsList(cartListPackageGoodsList);
                cartRespVO.setCartListPackage(cartPackageRespVO);
            }

            cartListRespVOS.add(cartRespVO);
        }

        return ResponseUtil.ok(cartListRespVOS);
    }

    public Response addCart(Integer userId, CartAddReqVO reqVO) {
        //当前门店
        LitemallShop shop = litemallShopService.findById(reqVO.getShopId());

        //动态设置门店时区
        dynamicTimeZoneConfiguration.setDynamicTimeZone(shop.getTimezone());


        //商品
        if(null != reqVO.getCartGoods()){
            LumiereCartGoods cartGoods = new LumiereCartGoods();
            LitemallGoods goods = goodsService.findById(reqVO.getCartGoods().getGoodsId());
            cartGoods.setGoodsId(goods.getId());
            cartGoods.setPrice(reqVO.getPrice());
            cartGoods.setNumber(reqVO.getCartGoods().getNumber());
            cartGoods.setSpecificationId(reqVO.getCartGoods().getFormulaSpecificationId());
            lumiereCartGoodsService.save(cartGoods);
            //保存商品属性
            List<CartAddGoodsPropertyReqVo> propertyList = reqVO.getCartGoods().getPropertyList();
            if(!CollectionUtils.isEmpty(propertyList)) {
                for (CartAddGoodsPropertyReqVo cartAddPropertyVo : propertyList) {
                    LumiereCartGoodsProperty cartGoodsProperty = new LumiereCartGoodsProperty();
                    cartGoodsProperty.setCartGoodsId(cartGoods.getId());
                    cartGoodsProperty.setGoodsPropertyId(cartAddPropertyVo.getGoodsPropertyId());
                    cartGoodsProperty.setName(cartAddPropertyVo.getName());
                    cartGoodsProperty.setValue(cartAddPropertyVo.getValue());
                    cartGoodsProperty.setCartGoodsId(cartGoods.getId());
                    lumiereCartGoodsPropertyService.save(cartGoodsProperty);
                }
            }

            //保存商品原料
            List<CartAddGoodsFormulaSpecificationsDataProportioningReqVO> formulaSpecificationsDataProportioningList = reqVO.getCartGoods().getFormulaSpecificationsDataProportioningList();
            if(CollUtil.isNotEmpty(formulaSpecificationsDataProportioningList)){
                for (CartAddGoodsFormulaSpecificationsDataProportioningReqVO cartAddGoodsFormulaSpecificationsDataProportioningReqVO : formulaSpecificationsDataProportioningList) {
                    LumiereCartGoodsFormulaSpecificationsDataProportioning cartGoodsFormulaSpecificationsDataProportioning = new LumiereCartGoodsFormulaSpecificationsDataProportioning();
                    cartGoodsFormulaSpecificationsDataProportioning.setCartGoodsId(cartGoods.getId());
                    cartGoodsFormulaSpecificationsDataProportioning.setFormulaSpecificationsDataProportioningId(cartAddGoodsFormulaSpecificationsDataProportioningReqVO.getId());
                    cartGoodsFormulaSpecificationsDataProportioning.setQuantity(cartAddGoodsFormulaSpecificationsDataProportioningReqVO.getQuantity());
                    cartGoodsFormulaSpecificationsDataProportioning.setPrice(cartAddGoodsFormulaSpecificationsDataProportioningReqVO.getConsumePrice());
                    cartGoodsFormulaSpecificationsDataProportioning.setGroupName(cartAddGoodsFormulaSpecificationsDataProportioningReqVO.getGroupName());
                    cartGoodsFormulaSpecificationsDataProportioning.setMakeUnit(cartAddGoodsFormulaSpecificationsDataProportioningReqVO.getMakeUnit());
                    lumiereCartGoodsFormulaSpecificationsDataProportioningService.save(cartGoodsFormulaSpecificationsDataProportioning);
                }
            }
            //购物车
            LumiereCart cart = new LumiereCart();
            cart.setUserId(userId);
            cart.setShopId(reqVO.getShopId());
            cart.setCartGoodsId(cartGoods.getId());
            cart.setType(0);
            cart.setPrice(reqVO.getPrice());
            lumiereCartService.save(cart);
            return ResponseUtil.ok(cart.getId());
        }else
        //套餐
        if(reqVO.getCartPackage()!=null){
            LumierePackage lumierePackage = lumierePackageService.getById(reqVO.getCartPackage().getPackageId());
            List<Integer> cartGoodsIds = new ArrayList<>();
            //套餐商品
            for (CartAddReqVO.CartAddGoodsReqVO cartAddGoodsReqVO : reqVO.getCartPackage().getGoodsList()) {
                LumiereCartGoods cartGoods = new LumiereCartGoods();
                LitemallGoods goods = goodsService.findById(cartAddGoodsReqVO.getGoodsId());
                cartGoods.setGoodsId(goods.getId());
                cartGoods.setPrice(cartAddGoodsReqVO.getPrice());
                cartGoods.setNumber(cartAddGoodsReqVO.getNumber());
                cartGoods.setSpecificationId(cartAddGoodsReqVO.getFormulaSpecificationId());
                lumiereCartGoodsService.save(cartGoods);
                //保存商品属性
                List<CartAddGoodsPropertyReqVo> propertyList = cartAddGoodsReqVO.getPropertyList();
                if(!CollectionUtils.isEmpty(propertyList)) {
                    for (CartAddGoodsPropertyReqVo cartAddPropertyVo : propertyList) {
                        LumiereCartGoodsProperty cartGoodsProperty = new LumiereCartGoodsProperty();
                        cartGoodsProperty.setCartGoodsId(cartGoods.getId());
                        cartGoodsProperty.setGoodsPropertyId(cartAddPropertyVo.getGoodsPropertyId());
                        cartGoodsProperty.setName(cartAddPropertyVo.getName());
                        cartGoodsProperty.setValue(cartAddPropertyVo.getValue());
                        cartGoodsProperty.setCartGoodsId(cartGoods.getId());
                        lumiereCartGoodsPropertyService.save(cartGoodsProperty);
                    }
                }

                //保存商品原料
                List<CartAddGoodsFormulaSpecificationsDataProportioningReqVO> formulaSpecificationsDataProportioningList = cartAddGoodsReqVO.getFormulaSpecificationsDataProportioningList();
                if(CollUtil.isNotEmpty(formulaSpecificationsDataProportioningList)){
                    for (CartAddGoodsFormulaSpecificationsDataProportioningReqVO cartAddGoodsFormulaSpecificationsDataProportioningReqVO : formulaSpecificationsDataProportioningList) {
                        LumiereCartGoodsFormulaSpecificationsDataProportioning cartGoodsFormulaSpecificationsDataProportioning = new LumiereCartGoodsFormulaSpecificationsDataProportioning();
                        cartGoodsFormulaSpecificationsDataProportioning.setCartGoodsId(cartGoods.getId());
                        cartGoodsFormulaSpecificationsDataProportioning.setFormulaSpecificationsDataProportioningId(cartAddGoodsFormulaSpecificationsDataProportioningReqVO.getId());
                        cartGoodsFormulaSpecificationsDataProportioning.setQuantity(cartAddGoodsFormulaSpecificationsDataProportioningReqVO.getQuantity());
                        cartGoodsFormulaSpecificationsDataProportioning.setPrice(cartAddGoodsFormulaSpecificationsDataProportioningReqVO.getConsumePrice());
                        cartGoodsFormulaSpecificationsDataProportioning.setGroupName(cartAddGoodsFormulaSpecificationsDataProportioningReqVO.getGroupName());
                        cartGoodsFormulaSpecificationsDataProportioning.setMakeUnit(cartAddGoodsFormulaSpecificationsDataProportioningReqVO.getMakeUnit());
                        lumiereCartGoodsFormulaSpecificationsDataProportioningService.save(cartGoodsFormulaSpecificationsDataProportioning);
                    }
                }

                cartGoodsIds.add(cartGoods.getId());
            }

            //套餐
            LumiereCartPackage cartPackage =new LumiereCartPackage();
            cartPackage.setNumber(reqVO.getCartPackage().getNumber());
            cartPackage.setPrice(lumierePackage.getAmount());
            cartPackage.setPackageId(lumierePackage.getId());
            cartPackage.setCartGoodsIds(cartGoodsIds);
            lumiereCartPackageService.save(cartPackage);

            //购物车
            LumiereCart cart = new LumiereCart();
            cart.setUserId(userId);
            cart.setShopId(reqVO.getShopId());
            cart.setCartPackageId(cartPackage.getId());
            cart.setType(1);
            cart.setPrice(reqVO.getPrice());
            lumiereCartService.save(cart);
            return ResponseUtil.ok(cart.getId());
        }
        return ResponseUtil.fail();
    }


    public Response delete(Integer userId, List<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return ResponseUtil.ok();
        }

        ids.forEach(id -> {
            LumiereCart cart = lumiereCartService.getById(id);
            if (Objects.isNull(cart) || !userId.equals(cart.getUserId().intValue())) {
                return; // 购物车为空或用户 ID 不匹配时跳过
            }
            deleteCartGoods(cart.getCartGoodsId());
            deleteCartPackage(cart.getCartPackageId());
            lumiereCartService.removeById(id); // 删除购物车项
        });

        return ResponseUtil.ok();
    }

    private void deleteCartGoods(Integer cartGoodsId) {
        if(null == cartGoodsId)return;
        LumiereCartGoods cartGoods = lumiereCartGoodsService.getById(cartGoodsId);
        if (Objects.nonNull(cartGoods)) {
            lumiereCartGoodsPropertyService.remove(Wrappers.lambdaQuery(LumiereCartGoodsProperty.class)
                    .eq(LumiereCartGoodsProperty::getCartGoodsId, cartGoods.getId()));
            lumiereCartGoodsFormulaSpecificationsDataProportioningService.remove(Wrappers.lambdaQuery(LumiereCartGoodsFormulaSpecificationsDataProportioning.class)
                    .eq(LumiereCartGoodsFormulaSpecificationsDataProportioning::getCartGoodsId, cartGoods.getId()));
            lumiereCartGoodsService.removeById(cartGoodsId); // 删除商品
        }
    }

    private void deleteCartPackage(Integer cartPackageId) {
        if(null == cartPackageId)return;
        LumiereCartPackage cartPackage = lumiereCartPackageService.getById(cartPackageId);
        if (Objects.nonNull(cartPackage)) {
            List<LumiereCartGoods> cartGoodsList = lumiereCartGoodsService.listByIds(cartPackage.getCartGoodsIds());
            List<Integer> cartGoodsIds = cartGoodsList.stream()
                    .map(LumiereCartGoods::getGoodsId)
                    .collect(Collectors.toList());

            lumiereCartGoodsPropertyService.remove(Wrappers.lambdaQuery(LumiereCartGoodsProperty.class)
                    .in(LumiereCartGoodsProperty::getCartGoodsId, cartGoodsIds));
            lumiereCartGoodsFormulaSpecificationsDataProportioningService.remove(Wrappers.lambdaQuery(LumiereCartGoodsFormulaSpecificationsDataProportioning.class)
                    .in(LumiereCartGoodsFormulaSpecificationsDataProportioning::getCartGoodsId, cartGoodsIds));

            lumiereCartGoodsService.removeBatchByIds(cartGoodsList); // 删除套餐中的商品
        }
    }


    public Response updateNum(Integer userId, Integer id, Integer num) {
        // 根据 ID 获取购物车项
        LumiereCart cart = lumiereCartService.getById(id);
        // 如果购物车项为空或者用户 ID 不匹配，则直接返回成功响应（不进行更新操作）
        if (Objects.isNull(cart) || userId!= cart.getUserId().intValue()) {
            return ResponseUtil.ok();
        }

        if (cart.getType() == 0) {
            // 如果是商品类型，获取对应的商品并更新数量
            LumiereCartGoods cartGoods = lumiereCartGoodsService.getById(cart.getCartGoodsId());
            cartGoods.setNumber(num);
            lumiereCartGoodsService.updateById(cartGoods);
        } else {
            // 如果是套餐类型，获取对应的套餐并更新数量
            LumiereCartPackage cartPackage = lumiereCartPackageService.getById(cart.getCartPackageId());
            cartPackage.setNumber(num);
            lumiereCartPackageService.updateById(cartPackage);
        }
        return ResponseUtil.ok();
    }

    private boolean checkShopMaterial(Integer userId,Integer shopId){
        List<LumiereCart> cartList = lumiereCartService.list(Wrappers.lambdaQuery(LumiereCart.class)
                .eq(LumiereCart::getShopId, shopId)
                .eq(LumiereCart::getUserId, userId));
        //获取购物车里所有的商品ID
        List<Integer> cartGoodsIdList = new ArrayList<>();
        for (LumiereCart cart : cartList) {
            if(cart.getType()==0){
                //计算商品 税率
                LumiereCartGoods cartGoods = lumiereCartGoodsService.getById(cart.getCartGoodsId());
                cartGoodsIdList.add(cartGoods.getId());
            }else {
                LumiereCartPackage cartPackage = lumiereCartPackageService.getById(cart.getCartPackageId());
                cartGoodsIdList.addAll(cartPackage.getCartGoodsIds());
            }
        }
        //商品是否下架
        List<LumiereCartGoods> cartGoodss = lumiereCartGoodsService.listByIds(cartGoodsIdList);

        List<CartCheckShopMaterialRespVO> cartCheckShopMaterialList = new ArrayList<>();

        for (LumiereCartGoods cartGoods : cartGoodss) {
            //判断商品是否可以购买
            LitemallGoods goods = goodsService.findById(cartGoods.getGoodsId());
            if (goods == null || !goods.getIsOnSale()) {
                //return ResponseUtil.fail(GOODS_UNSHELVE, "商品已下架");
            }

            List<LumiereCartGoodsFormulaSpecificationsDataProportioning> cartGoodsFormulaSpecificationsDataProportioningList = lumiereCartGoodsFormulaSpecificationsDataProportioningService.list(Wrappers.lambdaQuery(LumiereCartGoodsFormulaSpecificationsDataProportioning.class).eq(LumiereCartGoodsFormulaSpecificationsDataProportioning::getCartGoodsId,cartGoods.getId()));
            for (LumiereCartGoodsFormulaSpecificationsDataProportioning cartGoodsFormulaSpecificationsDataProportioning : cartGoodsFormulaSpecificationsDataProportioningList) {
                LumiereFormulaSpecificationsDataProportioning formulaSpecificationsDataProportioning = lumiereFormulaSpecificationsDataProportioningService.getById(cartGoodsFormulaSpecificationsDataProportioning.getFormulaSpecificationsDataProportioningId());
                LumiereFormulaMaterial formulaMaterial = lumiereFormulaMaterialService.getById(formulaSpecificationsDataProportioning.getFormulaMaterialId());
                cartCheckShopMaterialList.add(new CartCheckShopMaterialRespVO().setId(cartGoodsFormulaSpecificationsDataProportioning.getId())
                        .setMaterialId(formulaMaterial.getMaterialId())
                        .setQuantity(cartGoodsFormulaSpecificationsDataProportioning.getQuantity()*cartGoods.getNumber()));
            }
        }

        //分组
        Map<Integer, List<CartCheckShopMaterialRespVO>> cartCheckShopMaterialGroupMap = CollStreamUtil.groupByKey(cartCheckShopMaterialList, CartCheckShopMaterialRespVO::getMaterialId);
        //重新统计计算
        List<CartCheckShopMaterialRespVO> collect = cartCheckShopMaterialGroupMap.entrySet().stream()
                .map(entry -> {
                    Integer key = entry.getKey();
                    Integer sumQuantity = entry.getValue().stream()
                            .mapToInt(CartCheckShopMaterialRespVO::getQuantity)
                            .sum();
                    return new CartCheckShopMaterialRespVO().setMaterialId(key).setQuantity(sumQuantity);
                })
                .collect(Collectors.toList());
        for (CartCheckShopMaterialRespVO shopMaterialRespVO : collect) {
            //对比每一个的库存
            LitemallShopMerchandise shopMerchandise = litemallShopMerchandiseService.queryByMerIdAndShopId(shopMaterialRespVO.getMaterialId(), shopId);
            if(shopMerchandise.getNumber()<shopMaterialRespVO.getQuantity()){
                //原料不足
                //return ResponseUtil.fail(WxResponseEnum.GOODS_MERCHANDISE_NOTENOUGH);
            }else {
                //减去库存
                shopMerchandise.setNumber(shopMerchandise.getNumber()-shopMaterialRespVO.getQuantity());
                litemallShopMerchandiseService.updateById(shopMerchandise);
            }
        }
        return false;
    }


    //算账
    public Response<CartCheckOutRespVO> checkOut(Integer userId, CartCheckOutRequest cartCheckOutReq) {
        CartCheckOutRespVO cartCheckOutRespVO = new CartCheckOutRespVO();
        //当前门店
        LitemallShop shop = litemallShopService.findById(cartCheckOutReq.getShopId());

        //动态设置门店时区
        dynamicTimeZoneConfiguration.setDynamicTimeZone(shop.getTimezone());
        if (!shopCheckWeeksTime(shop)) {
            return ResponseUtil.fail(8008,"门店已歇业，请营业再来吧");
        }

        cartCheckOutRespVO.setShop(shop);

        Integer cityRegionId = getShopRegionId(cartCheckOutReq.getShopId());

        //会员优惠率
        MemberDiscountResultVO memberDiscountResult = computeMemberDiscountFromPayMembers(userId, cityRegionId);
        cartCheckOutRespVO.setWxMemberSourceVOList(memberDiscountResult.getWxMemberSourceVOList());
        cartCheckOutRespVO.setMemberPer(memberDiscountResult.getMemberPer());

        //获取当前用户门店 所有购物车商品
        List<CartWithMemberCouponRespVO> cartWithMemberCouponList = recomputeGoodsSumPriceExchange(cartCheckOutReq.getShopId(), userId,cartCheckOutReq.getCartIds());



        //总商品
        BigDecimal totalGoodsPrice = cartWithMemberCouponList.stream()
                .map(CartWithMemberCouponRespVO::getTotalPrice)
                .filter(price -> price!= null)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        cartCheckOutRespVO.setTotalGoodsPrice(totalGoodsPrice);

        recomputePriceWithMemberExchange(cartWithMemberCouponList,memberDiscountResult.getMemberPer());


        BigDecimal totalOnlyGoodsPrice = cartWithMemberCouponList.stream()
                .filter(cart -> cart.getType() == 0) // 假设这里有一个获取 type 的方法 getType()
                .map(CartWithMemberCouponRespVO::getTotalPrice)
                .filter(price -> price!= null)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        recomputePriceWithCouponExchange(cartWithMemberCouponList, totalOnlyGoodsPrice, getCartCouponStrategy(cartCheckOutReq.getCouponUserId()));

        //List<CartWithMemberCouponRespVO> cartWithMemberCouponList = recomputePriceWithMemberExchange(cartCheckOutReq.getShopId(), userId, memberDiscountResult.getMemberPer());


        //会员汇率优惠总金额
        BigDecimal memberDiscountSumPrices = cartWithMemberCouponList.stream()
                .map(CartWithMemberCouponRespVO::getMemberDiscountPrice)
                .filter(price -> price!= null)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        cartCheckOutRespVO.setMemberDiscountSumPrices(totalGoodsPrice.subtract(memberDiscountSumPrices));


        List<CartListRespVO> cartListRespVOS = new ArrayList<>();

        //优惠前金额
        //BigDecimal preDiscountAmount = new BigDecimal(0.00);
        //获取所有订单总价、税收总价
        BigDecimal totalPrice = new BigDecimal(0.00);

        BigDecimal totalGSTPrice = new BigDecimal(0.00);
        BigDecimal totalPSTPrice = new BigDecimal(0.00);
        BigDecimal totalHSTPrice = new BigDecimal(0.00);


        List<Integer> cartGoodsIds = new ArrayList<>();
        for (CartWithMemberCouponRespVO cart : cartWithMemberCouponList) {
            CartListRespVO cartRespVO = new CartListRespVO();
            cartRespVO.setId(cart.getId());
            cartRespVO.setAfterDiscountPrice(cart.getAfterDiscountPrice());
            cartRespVO.setPrice(cart.getPrice());
            cartRespVO.setType(cart.getType());

            if(cart.getType()==0){
                CartListRespVO.CartGoodsRespVO cartGoodsRespVO = new CartListRespVO.CartGoodsRespVO();

                //计算商品 税率
                LumiereCartGoods cartGoods = lumiereCartGoodsService.getById(cart.getCartGoodsId());

                //存储商品id
                cartGoodsIds.add(cartGoods.getGoodsId());

                LitemallGoodsRegion goodRegion = goodsRegionService.findByGidAndCityId(cartGoods.getGoodsId(), cityRegionId);

                //加上数量
                //cart.setAfterDiscountPrice(cart.getAfterDiscountPrice().multiply(BigDecimal.valueOf(cartGoods.getNumber())));
                totalPrice = totalPrice.add(cart.getAfterDiscountPrice());

                //preDiscountAmount = preDiscountAmount.add(cart.getPrice().multiply(BigDecimal.valueOf(cartGoods.getNumber())));

                if(goodRegion.getTaxTypes().length>0){
                    List<LitemallTax> taxList = litemallTaxService.selectEnabledByIds(Arrays.asList(goodRegion.getTaxTypes()));

                    List<CartListRespVO.CartListGoodsTaxRespVO> goodsTaxList = new ArrayList<>();

                    BigDecimal goodsGSTPrice = new BigDecimal(0.00);
                    BigDecimal goodsPSTPrice = new BigDecimal(0.00);
                    BigDecimal goodsHSTPrice = new BigDecimal(0.00);

                    for (LitemallTax tax : taxList) {
                        if(cart.getAfterDiscountPrice().compareTo(BigDecimal.ZERO) < 0) continue;

                        CartListRespVO.CartListGoodsTaxRespVO cartListGoodsTaxRespVO = new CartListRespVO.CartListGoodsTaxRespVO();
                        cartListGoodsTaxRespVO.setCode(tax.getCode());
                        cartListGoodsTaxRespVO.setValue(tax.getValue());

                        if(LitemallTax.TAX_GST.equals(tax.getCode())){
                            BigDecimal goodsTAX_GST = cart.getAfterDiscountPrice().multiply(tax.getValue()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
                            goodsGSTPrice = goodsGSTPrice.add(goodsTAX_GST);
                            totalGSTPrice = totalGSTPrice.add(goodsTAX_GST);

                            cartListGoodsTaxRespVO.setPrice(goodsTAX_GST);
                        }
                        if(LitemallTax.TAX_HST.equals(tax.getCode())){
                            BigDecimal goodsTAX_HST = cart.getAfterDiscountPrice().multiply(tax.getValue()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
                            goodsPSTPrice = goodsPSTPrice.add(goodsTAX_HST);
                            totalPSTPrice = totalPSTPrice.add(goodsTAX_HST);

                            cartListGoodsTaxRespVO.setPrice(goodsTAX_HST);
                        }
                        if(LitemallTax.TAX_PST.equals(tax.getCode())){
                            BigDecimal goodsTAX_PST = cart.getAfterDiscountPrice().multiply(tax.getValue()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
                            goodsHSTPrice = goodsHSTPrice.add(goodsTAX_PST);
                            totalHSTPrice = totalHSTPrice.add(goodsTAX_PST);

                            cartListGoodsTaxRespVO.setPrice(goodsTAX_PST);
                        }
                        goodsTaxList.add(cartListGoodsTaxRespVO);
                    }
                    cartGoodsRespVO.setGoodsTaxList(goodsTaxList);

                    //商品总税价
                    cartGoodsRespVO.setTaxPrice(goodsGSTPrice.add(goodsPSTPrice).add(goodsHSTPrice));
                }

                LitemallGoods goods = goodsService.findById(cartGoods.getGoodsId());
                //规格
                LumiereFormulaSpecifications formulaSpecifications = lumiereFormulaSpecificationsService.getById(cartGoods.getSpecificationId());

                cartGoodsRespVO.setId(cartGoods.getId());
                cartGoodsRespVO.setNumber(cartGoods.getNumber());
                cartGoodsRespVO.setGoodsId(goods.getId());
                cartGoodsRespVO.setName(goods.getName());
                cartGoodsRespVO.setPicUrl(goods.getPicUrl());
                cartGoodsRespVO.setSpecificationId(formulaSpecifications.getId());
                cartGoodsRespVO.setSpecificationsName(formulaSpecifications.getSpecificationsName());

                //属性
                List<LumiereCartGoodsProperty> cartGoodsProperties = lumiereCartGoodsPropertyService.list(Wrappers.lambdaQuery(LumiereCartGoodsProperty.class)
                        .eq(LumiereCartGoodsProperty::getCartGoodsId, cart.getCartGoodsId()));
                cartGoodsRespVO.setGoodsProperties(cartGoodsProperties);

                List<LumiereCartGoodsFormulaSpecificationsDataProportioning> cartGoodsFormulaSpecificationsDataProportionings = lumiereCartGoodsFormulaSpecificationsDataProportioningService.list(Wrappers.lambdaQuery(LumiereCartGoodsFormulaSpecificationsDataProportioning.class)
                        .eq(LumiereCartGoodsFormulaSpecificationsDataProportioning::getCartGoodsId, cartGoods.getId()));
                List<CartListRespVO.CartListGoodsFormulaSpecificationsDataProportioningRespVO> cartListGoodsFormulaSpecificationsDataProportioningList = new ArrayList<>();
                for (LumiereCartGoodsFormulaSpecificationsDataProportioning cartGoodsFormulaSpecificationsDataProportioning : cartGoodsFormulaSpecificationsDataProportionings) {

                    LumiereFormulaSpecificationsDataProportioning proportioningServiceById = lumiereFormulaSpecificationsDataProportioningService.getById(cartGoodsFormulaSpecificationsDataProportioning.getFormulaSpecificationsDataProportioningId());
                    LumiereFormulaMaterial formulaMaterial = lumiereFormulaMaterialService.getById(proportioningServiceById.getFormulaMaterialId());

                    CartListRespVO.CartListGoodsFormulaSpecificationsDataProportioningRespVO cartListGoodsFormulaSpecificationsDataProportioningRespVO = new CartListRespVO.CartListGoodsFormulaSpecificationsDataProportioningRespVO();
                    cartListGoodsFormulaSpecificationsDataProportioningRespVO.setId(cartGoodsFormulaSpecificationsDataProportioning.getId());
                    cartListGoodsFormulaSpecificationsDataProportioningRespVO.setFormulaSpecificationsDataProportioningId(proportioningServiceById.getId());
                    cartListGoodsFormulaSpecificationsDataProportioningRespVO.setQuantity(cartGoodsFormulaSpecificationsDataProportioning.getQuantity());
                    cartListGoodsFormulaSpecificationsDataProportioningRespVO.setPrice(cartGoodsFormulaSpecificationsDataProportioning.getPrice());
                    cartListGoodsFormulaSpecificationsDataProportioningRespVO.setMaterialId(formulaMaterial.getMaterialId());
                    cartListGoodsFormulaSpecificationsDataProportioningRespVO.setMaterialName(formulaMaterial.getMaterialName());
                    cartListGoodsFormulaSpecificationsDataProportioningRespVO.setMakeUnit(cartGoodsFormulaSpecificationsDataProportioning.getMakeUnit());
                    cartListGoodsFormulaSpecificationsDataProportioningList.add(cartListGoodsFormulaSpecificationsDataProportioningRespVO);
                }
                cartGoodsRespVO.setSpecificationsDataProportioningList(cartListGoodsFormulaSpecificationsDataProportioningList);
                cartRespVO.setCartGoods(cartGoodsRespVO);
            }else {
                //计算套餐 税率
                LumiereCartPackage cartPackage = lumiereCartPackageService.getById(cart.getCartPackageId());
                List<LumiereCartGoods> cartGoodsList = lumiereCartGoodsService.listByIds(cartPackage.getCartGoodsIds());

                //加上数量
                //cart.setAfterDiscountPrice(cart.getAfterDiscountPrice().multiply(BigDecimal.valueOf(cartPackage.getNumber())));

                totalPrice = totalPrice.add(cart.getAfterDiscountPrice());

                //preDiscountAmount = preDiscountAmount.add(cart.getPrice().multiply(BigDecimal.valueOf(cartPackage.getNumber())));

                CartListRespVO.CartPackageRespVO cartPackageRespVO = new CartListRespVO.CartPackageRespVO();
                LumierePackage lumierePackage = lumierePackageService.getById(cartPackage.getPackageId());

                //计算商品 税率
                LitemallGoodsRegion goodRegion = goodsRegionService.findByPackageIdAndCityId(cartPackage.getPackageId(), cityRegionId);

                List<CartListRespVO.CartListGoodsTaxRespVO> goodsTaxList = new ArrayList<>();

                if(goodRegion.getTaxTypes().length>0){
                    List<LitemallTax> taxList = litemallTaxService.selectEnabledByIds(Arrays.asList(goodRegion.getTaxTypes()));
                    BigDecimal goodsGSTPrice = new BigDecimal(0.00);
                    BigDecimal goodsPSTPrice = new BigDecimal(0.00);
                    BigDecimal goodsHSTPrice = new BigDecimal(0.00);

                    for (LitemallTax tax : taxList) {
                        if(cart.getAfterDiscountPrice().compareTo(BigDecimal.ZERO) < 0) continue;

                        CartListRespVO.CartListGoodsTaxRespVO cartListGoodsTaxRespVO = new CartListRespVO.CartListGoodsTaxRespVO();
                        cartListGoodsTaxRespVO.setCode(tax.getCode());
                        cartListGoodsTaxRespVO.setValue(tax.getValue());

                        if(LitemallTax.TAX_GST.equals(tax.getCode())){
                            BigDecimal goodsTAX_GST = cart.getAfterDiscountPrice().multiply(tax.getValue()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
                            goodsGSTPrice = goodsGSTPrice.add(goodsTAX_GST);
                            totalGSTPrice = totalGSTPrice.add(goodsTAX_GST);

                            cartListGoodsTaxRespVO.setPrice(goodsTAX_GST);
                        }
                        if(LitemallTax.TAX_HST.equals(tax.getCode())){
                            BigDecimal goodsTAX_HST = cart.getAfterDiscountPrice().multiply(tax.getValue()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
                            goodsPSTPrice = goodsPSTPrice.add(goodsTAX_HST);
                            totalPSTPrice = totalPSTPrice.add(goodsTAX_HST);

                            cartListGoodsTaxRespVO.setPrice(goodsTAX_HST);
                        }
                        if(LitemallTax.TAX_PST.equals(tax.getCode())){
                            BigDecimal goodsTAX_PST = cart.getAfterDiscountPrice().multiply(tax.getValue()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
                            goodsHSTPrice = goodsHSTPrice.add(goodsTAX_PST);
                            totalHSTPrice = totalHSTPrice.add(goodsTAX_PST);

                            cartListGoodsTaxRespVO.setPrice(goodsTAX_PST);
                        }
                        goodsTaxList.add(cartListGoodsTaxRespVO);
                    }

                }


                cartPackageRespVO.setId(cartPackage.getId());
                cartPackageRespVO.setPackageId(lumierePackage.getId());
                cartPackageRespVO.setNumber(cartPackage.getNumber());
                cartPackageRespVO.setPrice(cartPackage.getPrice());
                cartPackageRespVO.setPicUrl(lumierePackage.getPackageImg());
                cartPackageRespVO.setName(lumierePackage.getPackageName());

                List<CartListRespVO.CartGoodsRespVO> cartListPackageGoodsList = new ArrayList<>();


                for (LumiereCartGoods cartGoods : cartGoodsList) {
                    CartListRespVO.CartGoodsRespVO cartGoodsRespVO = new CartListRespVO.CartGoodsRespVO();

                    //套餐的税
                    cartGoodsRespVO.setGoodsTaxList(goodsTaxList);

                    LitemallGoods goods = goodsService.findById(cartGoods.getGoodsId());
                    //规格
                    LumiereFormulaSpecifications formulaSpecifications = lumiereFormulaSpecificationsService.getById(cartGoods.getSpecificationId());

                    cartGoodsRespVO.setId(cartGoods.getId());
                    cartGoodsRespVO.setNumber(cartGoods.getNumber());
                    cartGoodsRespVO.setName(goods.getName());
                    cartGoodsRespVO.setGoodsId(goods.getId());
                    cartGoodsRespVO.setPicUrl(goods.getPicUrl());
                    cartGoodsRespVO.setSpecificationId(formulaSpecifications.getId());
                    cartGoodsRespVO.setSpecificationsName(formulaSpecifications.getSpecificationsName());

                    //属性
                    List<LumiereCartGoodsProperty> cartGoodsProperties = lumiereCartGoodsPropertyService.list(Wrappers.lambdaQuery(LumiereCartGoodsProperty.class)
                            .eq(LumiereCartGoodsProperty::getCartGoodsId, cartGoods.getId()));
                    cartGoodsRespVO.setGoodsProperties(cartGoodsProperties);

                    List<LumiereCartGoodsFormulaSpecificationsDataProportioning> cartGoodsFormulaSpecificationsDataProportionings = lumiereCartGoodsFormulaSpecificationsDataProportioningService.list(Wrappers.lambdaQuery(LumiereCartGoodsFormulaSpecificationsDataProportioning.class)
                            .eq(LumiereCartGoodsFormulaSpecificationsDataProportioning::getCartGoodsId, cartGoods.getId()));
                    List<CartListRespVO.CartListGoodsFormulaSpecificationsDataProportioningRespVO> cartListGoodsFormulaSpecificationsDataProportioningList = new ArrayList<>();
                    for (LumiereCartGoodsFormulaSpecificationsDataProportioning cartGoodsFormulaSpecificationsDataProportioning : cartGoodsFormulaSpecificationsDataProportionings) {

                        LumiereFormulaSpecificationsDataProportioning proportioningServiceById = lumiereFormulaSpecificationsDataProportioningService.getById(cartGoodsFormulaSpecificationsDataProportioning.getFormulaSpecificationsDataProportioningId());
                        LumiereFormulaMaterial formulaMaterial = lumiereFormulaMaterialService.getById(proportioningServiceById.getFormulaMaterialId());

                        CartListRespVO.CartListGoodsFormulaSpecificationsDataProportioningRespVO cartListGoodsFormulaSpecificationsDataProportioningRespVO = new CartListRespVO.CartListGoodsFormulaSpecificationsDataProportioningRespVO();
                        cartListGoodsFormulaSpecificationsDataProportioningRespVO.setId(cartGoodsFormulaSpecificationsDataProportioning.getId());
                        cartListGoodsFormulaSpecificationsDataProportioningRespVO.setFormulaSpecificationsDataProportioningId(proportioningServiceById.getId());
                        cartListGoodsFormulaSpecificationsDataProportioningRespVO.setQuantity(cartGoodsFormulaSpecificationsDataProportioning.getQuantity());
                        cartListGoodsFormulaSpecificationsDataProportioningRespVO.setPrice(cartGoodsFormulaSpecificationsDataProportioning.getPrice());
                        cartListGoodsFormulaSpecificationsDataProportioningRespVO.setMaterialId(formulaMaterial.getMaterialId());
                        cartListGoodsFormulaSpecificationsDataProportioningRespVO.setMaterialName(formulaMaterial.getMaterialName());
                        cartListGoodsFormulaSpecificationsDataProportioningRespVO.setMakeUnit(cartGoodsFormulaSpecificationsDataProportioning.getMakeUnit());
                        cartListGoodsFormulaSpecificationsDataProportioningList.add(cartListGoodsFormulaSpecificationsDataProportioningRespVO);
                    }
                    cartGoodsRespVO.setSpecificationsDataProportioningList(cartListGoodsFormulaSpecificationsDataProportioningList);

                    cartListPackageGoodsList.add(cartGoodsRespVO);
                }
                cartPackageRespVO.setCartListGoodsList(cartListPackageGoodsList);
                cartRespVO.setCartListPackage(cartPackageRespVO);
            }
            cartListRespVOS.add(cartRespVO);
        }

        //计算优惠的金额
        //cartCheckOutRespVO.setMemberDiscountSumPrices(preDiscountAmount.subtract(totalPrice));


        //计算优惠券 优惠金额 memberDiscountSumPrices * 0.0  | memberDiscountSumPrices - 7
        //cartCheckOutRespVO.setCouponDiscountPrice(calculateFinalPrice(totalPrice,cartCheckOutReq.getCouponUserId()));  // 确保最终价格不为负数

        //运费
        // 根据订单商品总价计算运费，满88则免运费，否则8元；
        BigDecimal freightPrice = new BigDecimal(0.00);
        if (totalPrice.subtract(cartCheckOutRespVO.getCouponDiscountPrice()).compareTo(SystemConfig.getFreightLimit()) < 0) {
            freightPrice = SystemConfig.getFreight();
        }
        cartCheckOutRespVO.setShopFreightPrice(freightPrice);

        // 获取优惠券减免金额，优惠券可用数量
        cartCheckOutRespVO.setAvailableCouponList(CollStreamUtil.toList(getAvailableCoupons(userId,memberDiscountSumPrices,cartCheckOutReq.getShopId(),cartGoodsIds),LumiereCouponUser::getId));

        //优惠券优惠总金额
       BigDecimal couponDiscountPrice = cartWithMemberCouponList.stream()
                .map(CartWithMemberCouponRespVO::getCouponDiscountPrice)
                .filter(price -> price!= null)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        cartCheckOutRespVO.setCouponDiscountPrice(couponDiscountPrice);


        cartCheckOutRespVO.setCartList(cartListRespVOS);

        //cartCheckOutRespVO.setTotalGoodsPrice(preDiscountAmount);
        //GST PST HST
        cartCheckOutRespVO.setTotalGSTPrice(totalGSTPrice);
        cartCheckOutRespVO.setTotalHSTPrice(totalPSTPrice);
        cartCheckOutRespVO.setTotalPSTPrice(totalHSTPrice);
        //总税价
        cartCheckOutRespVO.setTaxTotalPrice(totalGSTPrice.add(totalPSTPrice).add(totalHSTPrice));
        //订单总价
        cartCheckOutRespVO.setTotalPrice(totalPrice.add(cartCheckOutRespVO.getTaxTotalPrice()));
        return ResponseUtil.ok(cartCheckOutRespVO);
    }

    public CouponDiscountResultVO getCartCouponStrategy(Long couponUserId) {
        if (couponUserId == null) {
            return new CouponDiscountResultVO().setDiscount(BigDecimal.ZERO).setDiscountType((byte) 1);
            //return BigDecimal.ZERO; // 没有使用优惠券，优惠金额为0
        }

        // 获取优惠券用户信息
        LumiereCouponUser couponUser = lumiereCouponUserService.getById(couponUserId);
        if (couponUser == null) {
            return new CouponDiscountResultVO().setDiscount(BigDecimal.ZERO).setDiscountType((byte)1);
            //return BigDecimal.ZERO; // 优惠券用户不存在，优惠金额为0
        }

        // 获取优惠券策略信息
        LumiereCouponStrategy couponStrategy = lumiereCouponStrategyService.findByid(couponUser.getStrategyId());
        return new CouponDiscountResultVO()
                .setDiscount(couponStrategy.getDiscountType() == 1?couponStrategy.getDiscount():couponStrategy.getDiscountRate())
                .setDiscountType(couponStrategy.getDiscountType());
        //return couponStrategy.getDiscountType() == 1?couponStrategy.getDiscount():couponStrategy.getDiscountRate();
    }

    //计算折扣后的最终金额
    /*public BigDecimal calculateFinalPrice(BigDecimal totalPrice, Long couponUserId) {
        if (couponUserId == null) {
            return BigDecimal.ZERO; // 没有使用优惠券，优惠金额为0
        }

        // 获取优惠券用户信息
        LumiereCouponUser couponUser = lumiereCouponUserService.getById(couponUserId);
        if (couponUser == null) {
            return BigDecimal.ZERO; // 优惠券用户不存在，优惠金额为0
        }

        // 获取优惠券策略信息
        LumiereCouponStrategy couponStrategy = lumiereCouponStrategyService.findByid(couponUser.getStrategyId());
        if (couponStrategy == null) {
            return BigDecimal.ZERO; // 优惠券策略不存在，优惠金额为0
        }

        BigDecimal discountAmount;

        // 判断折扣类型 (1: 满减, 2: 百分比)
        if (couponStrategy.getDiscountType() == 2) {
            // 百分比折扣
            BigDecimal discountRate = couponStrategy.getDiscountRate().divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
            discountAmount = totalPrice.multiply(discountRate);
        } else {
            // 满减折扣
            discountAmount = couponStrategy.getDiscount();
        }

        // 返回优惠金额，确保优惠金额不超过总价
        return discountAmount.min(totalPrice);
    }*/

    //获取用户可用的优惠券列表
    public List<LumiereCouponUser> getAvailableCoupons(Integer userId, BigDecimal memberDiscountSumPrices, Integer shopId, List<Integer> cartGoodsIds) {
        //全是套餐就不能使用优惠券
        if(cartGoodsIds.size()==0)return CollUtil.newArrayList();
        // 获取用户的所有优惠券
        List<LumiereCouponUser> lumiereCouponUsers = lumiereCouponUserService.list(Wrappers.lambdaQuery(LumiereCouponUser.class)
                .eq(LumiereCouponUser::getUserId, userId));
        // 校验优惠券策略，获取可用优惠券列表
        return couponVerifyService.checkCouponStrategy(lumiereCouponUsers, memberDiscountSumPrices, 1, shopId, cartGoodsIds);
    }

    //计算商品的总价
    private List<CartWithMemberCouponRespVO> recomputeGoodsSumPriceExchange(Integer shopId,Integer userId,List<Integer> cartIds){
        List<LumiereCart> cartList = lumiereCartService.list(Wrappers.lambdaQuery(LumiereCart.class)
                .in(CollUtil.isNotEmpty(cartIds),LumiereCart::getId,cartIds)
                .eq(LumiereCart::getShopId, shopId)
                .eq(LumiereCart::getUserId, userId));
        return CollStreamUtil.toList(cartList, cart -> {
            CartWithMemberCouponRespVO cartWithMemberCoupon = BeanUtil.toBean(cart, CartWithMemberCouponRespVO.class);
            if(cart.getType()==0){
                //计算商品 税率
                LumiereCartGoods cartGoods = lumiereCartGoodsService.getById(cart.getCartGoodsId());
                cartWithMemberCoupon.setTotalPrice(cart.getPrice().multiply(BigDecimal.valueOf(cartGoods.getNumber())));
            }else {
                LumiereCartPackage cartPackage = lumiereCartPackageService.getById(cart.getCartPackageId());
                cartWithMemberCoupon.setTotalPrice(cart.getPrice().multiply(BigDecimal.valueOf(cartPackage.getNumber())));
            }
            return cartWithMemberCoupon;
        });
    }

    //使用会员汇率重新计算价格
    private List<CartWithMemberCouponRespVO> recomputePriceWithMemberExchange(List<CartWithMemberCouponRespVO> cartWithMemberCouponList,BigDecimal memberPer){
        cartWithMemberCouponList.forEach(cartWithMemberCoupon -> {
            //会员汇率
            if(cartWithMemberCoupon.getType() == 0){
                BigDecimal discountPrice = memberPer.compareTo(BigDecimal.ZERO) == 0? BigDecimal.ZERO : cartWithMemberCoupon.getTotalPrice().multiply(memberPer);
                cartWithMemberCoupon.setMemberDiscountPrice(cartWithMemberCoupon.getTotalPrice().subtract(discountPrice));
                //cartWithMemberCoupon.setMemberDiscountPrice(cartWithMemberCoupon.getTotalPrice().multiply(memberPer));
                /*cartWithMemberCoupon.setMemberDiscountPrice(memberPer.compareTo(BigDecimal.ZERO) == 0? cartWithMemberCoupon.getPrice() :
                        cartWithMemberCoupon.getPrice().subtract(cartWithMemberCoupon.getPrice().multiply(memberPer)));*/
            }else {
                cartWithMemberCoupon.setMemberDiscountPrice(cartWithMemberCoupon.getTotalPrice());
            }

        });
        return cartWithMemberCouponList;
    }


    //使用优惠券重新计算价格
    private List<CartWithMemberCouponRespVO> recomputePriceWithCouponExchange(List<CartWithMemberCouponRespVO> cartWithMemberCouponList,BigDecimal totalGoodsPrice,CouponDiscountResultVO couponStrategy){
        cartWithMemberCouponList.forEach(cartWithMemberCoupon -> {
            //会员汇率
            if(cartWithMemberCoupon.getType() == 0 && couponStrategy.getDiscount().compareTo(BigDecimal.ZERO)>0){
                //商品金额占总金额的百分百
                BigDecimal goodsAmountRatioToTotal = cartWithMemberCoupon.getTotalPrice().divide(totalGoodsPrice,2, BigDecimal.ROUND_HALF_UP);
                if(couponStrategy.getDiscountType()==1){
                    cartWithMemberCoupon.setCouponDiscountPrice(goodsAmountRatioToTotal.multiply(couponStrategy.getDiscount()));
                }else {
                    cartWithMemberCoupon.setCouponDiscountPrice(cartWithMemberCoupon.getMemberDiscountPrice().multiply(couponStrategy.getDiscount().divide(new BigDecimal(100))));
                }
                cartWithMemberCoupon.setAfterDiscountPrice(cartWithMemberCoupon.getMemberDiscountPrice().subtract(cartWithMemberCoupon.getCouponDiscountPrice()));
            }else {
                cartWithMemberCoupon.setCouponDiscountPrice(BigDecimal.ZERO);
                cartWithMemberCoupon.setAfterDiscountPrice(cartWithMemberCoupon.getMemberDiscountPrice());
            }
        });
        return cartWithMemberCouponList;
    }

    /*//使用会员汇率和优惠券重新计算价格
    private List<CartWithMemberCouponRespVO> recomputePriceWithMemberExchange(Integer shopId,Integer userId,BigDecimal memberPer){
        List<LumiereCart> cartList = lumiereCartService.list(Wrappers.lambdaQuery(LumiereCart.class)
                .eq(LumiereCart::getShopId, shopId)
                .eq(LumiereCart::getUserId, userId));
        return CollStreamUtil.toList(cartList, cart -> {
            CartWithMemberCouponRespVO cartWithMemberCoupon = BeanUtil.toBean(cart, CartWithMemberCouponRespVO.class);
            //会员汇率
            cartWithMemberCoupon.setAfterDiscountPrice(memberPer.compareTo(BigDecimal.ZERO) == 0? cart.getPrice() :
                    cart.getPrice().subtract(cart.getPrice().multiply(memberPer)));
            return cartWithMemberCoupon;
        });
    }*/

    //使用会员汇率和优惠券重新计算价格
    /*private List<CartWithMemberCouponRespVO> recomputePriceCouponExchange(Integer shopId,Integer userId,BigDecimal memberPer){
        List<LumiereCart> cartList = lumiereCartService.list(Wrappers.lambdaQuery(LumiereCart.class)
                .eq(LumiereCart::getShopId, shopId)
                .eq(LumiereCart::getUserId, userId));
        return CollStreamUtil.toList(cartList, cart -> {
            CartWithMemberCouponRespVO cartWithMemberCoupon = BeanUtil.toBean(cart, CartWithMemberCouponRespVO.class);
            //优惠券
            cartWithMemberCoupon.setAfterDiscountPrice(memberPer.compareTo(BigDecimal.ZERO) == 0? cart.getPrice() :
                    cart.getPrice().subtract(cart.getPrice().multiply(memberPer)));
            return cartWithMemberCoupon;
        });
    }*/


    //表示从付费会员数据中计算会员折扣
    private MemberDiscountResultVO computeMemberDiscountFromPayMembers(Integer userId,Integer cityRegionId){
        BigDecimal memberPer = new BigDecimal(0);
        //优惠来源
        List<WxMemberSourceDTO> wxMemberSourceVOList = CollUtil.newArrayList();
        List<LumierePayMemberUser> payMemberUsers = payMemberUserService.listMemberByUserId(userId);

        Boolean notOverlay = false;
        BigDecimal maxMemberPer = new BigDecimal(0);
        //叠加付费会员优惠比例
        for(LumierePayMemberUser payMemberUser : payMemberUsers){
            //获得付费会员
            LumierePayMember payMember = lumierePayMemberService.findById(payMemberUser.getPayMemberId());
            //判断可以在该店使用
            Boolean result = payMember.getShopIds()!=null?ArrayUtil.contains(payMember.getShopIds(), cityRegionId):true;
            //当付费会员允许 汇率叠加
            if(payMember.getIsOverlay()==1 && result &&payMember.getDicountPer() != null){
                memberPer=memberPer.add((payMember.getDicountPer().divide(new BigDecimal(100)))).setScale(2, BigDecimal.ROUND_HALF_UP);
                //会员优惠来源
                wxMemberSourceVOList.add(new WxMemberSourceDTO(payMember.getDicountPer().divide(new BigDecimal(100)),payMember.getName()));
                notOverlay=true;
            }
            //选择一个最高的会员优惠率
            if(payMember.getDicountPer()!=null&&(memberPer.compareTo(payMember.getDicountPer())==-1)){
                maxMemberPer=payMember.getDicountPer();
            }
        }
        //如果没有一个会员叠加，则选择一个最高的会员优惠率
        memberPer=notOverlay==false?maxMemberPer.divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP):memberPer;
        return new MemberDiscountResultVO().setMemberPer(memberPer).setWxMemberSourceVOList(wxMemberSourceVOList);
    }

    public Response getAvailableCartCoupons(CartAvailableCartCouponsReqVO reqVO) {
        List<CartAvailableCartCouponsRespVO> couponVoList = new ArrayList();
        if(CollUtil.isEmpty(reqVO.getAvailableCouponList())) return ResponseUtil.ok(couponVoList);
        List<LumiereCouponUser> couponUserList = lumiereCouponUserService.listByIds(reqVO.getAvailableCouponList());
        for (LumiereCouponUser couponUser : couponUserList) {
            LumiereCoupon coupon = lumiereCouponService.getById(couponUser.getCouponId());
            LumiereCouponStrategy couponStrategy = lumiereCouponStrategyService.getById(couponUser.getStrategyId());

            CartAvailableCartCouponsRespVO couponVo = new CartAvailableCartCouponsRespVO();
            couponVo.setId(couponUser.getId());
            couponVo.setName(couponStrategy.getName());
            couponVo.setCouponType(couponStrategy.getCouponType());
            couponVo.setDescr(coupon.getDescr());
            couponVo.setMin(couponStrategy.getMin());
            couponVo.setCode(coupon.getCode().toString());
            couponVo.setPictureUrl(coupon.getPictureUrl());

            couponVo.setDiscount(couponStrategy.getDiscount());
            couponVo.setStartTime(couponUser.getStartTime());
            couponVo.setEndTime(couponUser.getEndTime());
            couponVo.setDiscountRate(couponStrategy.getDiscountRate().byteValue());
            couponVo.setDiscountType(couponStrategy.getDiscountType());
            couponVo.setUseLimit(couponStrategy.getUseLimit());
            couponVo.setUseLimitNum(couponStrategy.getUseLimitNum());

            //拼接指定商品，指定分类，指定地区
            String userInstruction = "";

            if (couponStrategy.getUseInstruction() != null) {
                userInstruction += "其他说明如下: " + "\r\n";
                userInstruction += "          " + couponStrategy.getUseInstruction() + "\r\n";
                couponVo.getLimitUseInstruction().add(couponStrategy.getUseInstruction());
            }

            //获取地区限制
            if(couponStrategy.getRegions().length!=0){
                List<LitemallRegion> litemallRegions = regionService.findByIds(Arrays.asList(couponStrategy.getRegions()));
                couponVo.setLimitRegionslist(CollStreamUtil.toList(litemallRegions,LitemallRegion::getNameEn));
            }

            //类目限制
            if(couponStrategy.getGoodsValue().length>0){
                List<LitemallCategory> categoryList = litemallCategoryService.selectCategoryByIdsInL3(Arrays.asList(couponStrategy.getGoodsValue()));
                couponVo.setLimitCategories(CollStreamUtil.toList(categoryList,LitemallCategory::getName));
            }

            //商品限制
            if(couponStrategy.getSelectGoods().length>0){
                List<LitemallGoods> goodsList = goodsService.findByIds(Arrays.asList(couponStrategy.getSelectGoods()));
                couponVo.setLimitGoods(CollStreamUtil.toList(goodsList,LitemallGoods::getName));
            }

            couponVo.setUseInstruction(userInstruction);
            couponVoList.add(couponVo);
        }
        return ResponseUtil.ok(couponVoList);
    }




    /**
     * 获取店铺的地区id
     * @param shopId
     */
    public Integer getShopCityRegionId(Integer shopId) {
        List<LitemallShopRegion> litemallShopRegions = shopRegionService.queryByShopId(shopId);
        if(!CollectionUtils.isEmpty(litemallShopRegions)) {
            for (LitemallShopRegion litemallShopRegion : litemallShopRegions) {
                LitemallRegion litemallRegion = litemallRegionService.findById(litemallShopRegion.getRegionId());
                if(Constants.REGION_TYPE_CITY == litemallRegion.getType()) {
                    return litemallShopRegion.getRegionId();
                }
            }
        }
        return null;
    }

    /*public Response<CartIndexResponse> index(Integer userId,Integer shopId) {

        //反显对象
    	CartIndexResponse response = CartIndexResponse.builder().build();
        //购物车商品VOs
        List<CartIndexInfoVo> rtn = new ArrayList<>();
        //获得当前用户门店下的购物车商品集合
        List<LitemallCart> cartList = cartService.queryByUidAndSid(userId,shopId);
        Integer goodsCount = 0;
        BigDecimal goodsAmount = new BigDecimal(0.00);//SpecificationIds
        Integer checkedGoodsCount = 0;
        BigDecimal checkedGoodsAmount = new BigDecimal(0.00);
        for (LitemallCart cart : cartList) {
            LitemallShop shop = litemallShopService.findById(cart.getShopId());
            if(shop != null){
                cart.setShopName(shop.getName());
            }
            //购物车商品的数量
            goodsCount += cart.getNumber();
            goodsAmount = goodsAmount.add(cart.getPrice().multiply(new BigDecimal(cart.getNumber())));
            if (cart.getChecked()) {
                checkedGoodsCount += cart.getNumber();
                checkedGoodsAmount = checkedGoodsAmount.add(cart.getPrice().multiply(new BigDecimal(cart.getNumber())));
            }

            CartIndexInfoVo vo = new CartIndexInfoVo();
            BeanUtils.copyProperties(cart, vo);

            Integer cartId = cart.getId();
            List<LitemallCartGoodsAccessory> accessories = litemallCartGoodsAccessoryService.queryByCartId(cartId);
            if(accessories != null){
                List<AccessoryVo> collect = accessories.stream().map(item -> {
                    LitemallGoodsAccessory accessory = litemallGoodsAccessoryService.findById(item.getAccessoryId());
                    AccessoryVo accessoryVo = new AccessoryVo();
                    BeanUtils.copyProperties(accessory, accessoryVo);
                    accessoryVo.setSelectNum(item.getNumber());
                    return accessoryVo;
                }).collect(Collectors.toList());
                vo.setAccessories(collect);
            }

            List<LitemallCartGoodsProperty> propertyList = litemallCartGoodsPropertyService.queryByCartId(cartId);
            if(!CollectionUtils.isEmpty(propertyList)) {
            	List<PropertyVo> collect = propertyList.stream().map(item -> {
            		LitemallGoodsProperty litemallGoodsProperty = litemallGoodsPropertyService.findById(item.getGoodsPropertyId());
            		PropertyVo propVo = new PropertyVo();
                    BeanUtils.copyProperties(litemallGoodsProperty, propVo);
                    propVo.setSelectValue(item.getValue());
                    return propVo;
                }).collect(Collectors.toList());
            	vo.setPropList(collect);
            }
            rtn.add(vo);
        }
        //购物车信息响应数据计算类
        CartIndexCountVo cartTotal = CartIndexCountVo.builder().build();
        cartTotal.setGoodsCount(goodsCount);
        cartTotal.setGoodsAmount(goodsAmount);
        cartTotal.setCheckedGoodsCount(checkedGoodsCount);
        cartTotal.setCheckedGoodsAmount(checkedGoodsAmount);

        response.setCartList(rtn);
        response.setCartTotal(cartTotal);

        return ResponseUtil.ok(response);
    }*/



    /*public Object add(Integer userId, CartDTO cartDto) {
        if (cartDto == null) {
            return ResponseUtil.badArgument();
        }
        Integer shopId = cartDto.getShopId();
        Integer productId = cartDto.getProductId();
        Integer number = cartDto.getNumber().intValue();
        Integer goodsId = cartDto.getGoodsId();
        Integer[] specIds = cartDto.getSpecificationIds();
        if (!ObjectUtils.allNotNull(productId, number, goodsId, shopId)) {
            return ResponseUtil.badArgument();
        }
        if(number <= 0){
            return ResponseUtil.badArgument();
        }

        //购物车辅料
        List<LitemallCartGoodsAccessory> cartGoodsAccessories = new ArrayList<>();
        //判断商品是否可以购买
        LitemallGoods goods = goodsService.findById(goodsId);
        if (goods == null || !goods.getIsOnSale()) {
            return ResponseUtil.fail(GOODS_UNSHELVE, "商品已下架");
        }

        LitemallGoodsProduct product = productService.findById(productId);
        //判断购物车中是否存在此规格商品
        LitemallCart existCart = cartService.queryExist(goodsId, productId, userId, specIds);
        if(existCart != null && cartDto.getCartGoodsAccessoryList() != null && cartDto.getCartGoodsAccessoryList().size() > 0){
            //先判断总数
            if(litemallCartGoodsAccessoryService.countByCartId(existCart.getId()) != cartDto.getCartGoodsAccessoryList().size()){
                existCart = null;
            }else{
                //单个判断
                for(LitemallCartGoodsAccessory item : cartDto.getCartGoodsAccessoryList()){
                    if(!litemallCartGoodsAccessoryService.exist(existCart.getId(), item.getAccessoryId(), item.getNumber())){
                        existCart = null;
                        break;
                    }
                }
            }
        }
        if (existCart == null) {
            //取得规格的信息,判断规格库存
            if (goods.getType() == 1 && product == null) {
                return ResponseUtil.fail(GOODS_NO_STOCK, "库存不足");
            }

            cartDto.setId(null);
            cartDto.setShopId(shopId);
            cartDto.setGoodsSn(goods.getGoodsSn());
            cartDto.setGoodsName((goods.getName()));
            cartDto.setPicUrl(goods.getPicUrl());
            BigDecimal sellPrice = product.getSellPrice().multiply(new BigDecimal(number));
            List<String> specifications = new ArrayList<>();
            //规格价格
            if(null != specIds && specIds.length > 0 ){
                cartDto.setSpecificationIds(specIds);
                List<LitemallGoodsSpecification> litemallGoodsSpecifications = specificationService.queryByIds(specIds);
                for(LitemallGoodsSpecification item : litemallGoodsSpecifications){
                    sellPrice = sellPrice.add(item.getPrice());
                    specifications.add(item.getValue());
                }
            }
            //辅料价格
            if(cartDto.getCartGoodsAccessoryList() != null && cartDto.getCartGoodsAccessoryList().size() > 0){
                for(LitemallCartGoodsAccessory item : cartDto.getCartGoodsAccessoryList()){
                    LitemallGoodsAccessory accessory = litemallGoodsAccessoryService.findById(item.getAccessoryId());
                    LitemallShopMerchandise merchandise = litemallShopMerchandiseService.queryByMerIdAndShopId(accessory.getMerchandiseId(), shopId);
                    if(merchandise == null || merchandise.getNumber() < item.getNumber() * number){
                        return ResponseUtil.fail(WxResponseEnum.ACCESSORY_ENOUGH);
                    }
                    //设置辅料项
                    item.setGoodsId(accessory.getGoodsId());
                    item.setAccessoryId(accessory.getId());
                    item.setPrice(accessory.getPrice());
                    cartGoodsAccessories.add(item);
                    sellPrice = sellPrice.add(item.getPrice().multiply(new BigDecimal(item.getNumber())));
                }
            }
            cartDto.setPrice(sellPrice);
            cartDto.setSpecifications(specifications.toArray(new String[]{}));
            cartDto.setSpecificationIds(specIds);
            cartDto.setUserId(userId);
            cartDto.setChecked(true);
            cartDto.setProductId(product.getId());
            LitemallCart cart = new LitemallCart();
            cart.setGoodsPrice(product.getSellPrice());
            BeanUtils.copyProperties(cartDto, cart);
            cartService.add(cart);
            for(LitemallCartGoodsAccessory item : cartGoodsAccessories) {
                item.setCartId(cart.getId());
                litemallCartGoodsAccessoryService.add(item);
            }
        } else {
            //取得规格的信息,判断规格库存
            int num = existCart.getNumber() + number;
            if (num > product.getNumber()) {
                return ResponseUtil.fail(GOODS_NO_STOCK, "库存不足");
            }
            if(cartDto.getCartGoodsAccessoryList() != null && cartDto.getCartGoodsAccessoryList().size() > 0) {
                for (LitemallCartGoodsAccessory item : cartDto.getCartGoodsAccessoryList()) {
                    LitemallGoodsAccessory accessory = litemallGoodsAccessoryService.findById(item.getAccessoryId());
                    LitemallShopMerchandise merchandise = litemallShopMerchandiseService.queryByMerIdAndShopId(accessory.getMerchandiseId(), shopId);
                    if (merchandise == null || merchandise.getNumber() < item.getNumber() * number) {
                        return ResponseUtil.fail(WxResponseEnum.ACCESSORY_ENOUGH);
                    }
                }
            }
            existCart.setNumber((short) num);
            if (cartService.updateById2(existCart) == 0) {
                return ResponseUtil.updatedDataFailed();
            }
        }

        return goodscount(userId);
    }*/
    /**
     * 加入商品到购物车
     * <p>
     * 如果已经存在购物车货品，则增加数量；
     * 否则添加新的购物车货品项。
     *
     * @param userId 用户ID
     * @param request   购物车商品请求
     * @return 加入购物车操作结果
     */
    /*public Object add(Integer userId, CartAddRequest request) {
        if (request == null) {
            return ResponseUtil.badArgument();
        }
        Integer shopId = request.getShopId();
        Integer number = request.getNumber();
        Integer goodsId = request.getGoodsId();
        Integer[] specIds = request.getSpecIds();
        if (!ObjectUtils.allNotNull(number, goodsId, shopId)) {
            return ResponseUtil.badArgument();
        }
        if(number <= 0){
            return ResponseUtil.badArgument();
        }

        //判断商品是否可以购买
        LitemallGoods goods = goodsService.findById(goodsId);
        if (goods == null || !goods.getIsOnSale()) {
        	return ResponseUtil.fail(GOODS_UNSHELVE, "商品已下架");
        }

        //判断购物车中是否存在此规格辅料相同的商品
        LitemallCart existCart = null;
        List<LitemallCart> existCartLs = cartService.queryByGidAndUidAndSpecIds(goodsId, userId, specIds,shopId);
        if(!CollectionUtils.isEmpty(existCartLs)) {
        	//获得添加的辅料列表
    		List<CartAddAccessoryVo> accessoryParam = request.getAccessoryList();
    		int accessorySize = accessoryParam != null? accessoryParam.size():0;
    		//获得添加的属性列表
    		List<CartAddPropertyVo> propertyParam = request.getPropertyList();
    		int propertySize = propertyParam != null? propertyParam.size():0;
    		for (LitemallCart litemallCart : existCartLs) {
    			Integer cartId = litemallCart.getId();

    			boolean samePropertyflag = false;//设置请求添加的商品与该订单商品属性相同标志
				if( propertySize ==  litemallCartGoodsPropertyService.countByCartId(cartId).intValue()) {
					boolean flag = true;

					if(propertySize > 0) {
						for (CartAddPropertyVo cartAddPropertyVo : propertyParam) {
							LitemallCartGoodsProperty litemallCartGoodsProperty = litemallCartGoodsPropertyService.findByCartIdAndGoodsPropertyIdAndValue
									(cartId, cartAddPropertyVo.getGoodsPropertyId(), cartAddPropertyVo.getValue().trim());
							if(null == litemallCartGoodsProperty) {
								flag = false;
								break;
							}
						}
					}

					if(flag) {
						samePropertyflag = true;
					}
				}

				boolean sameAccessoryflag = false;//设置请求添加的商品与该订单商品辅料相同标志
				if(samePropertyflag) {//说明属性值相同
					if(litemallCartGoodsAccessoryService.countByCartId(litemallCart.getId()) == accessorySize) {
						boolean flag = true;
						if(accessorySize > 0) {
							//单个判断
							for(CartAddAccessoryVo item : accessoryParam){
								if(!litemallCartGoodsAccessoryService.exist(litemallCart.getId(), item.getAccessoryId(), item.getNumber())){
									flag = false;
									break;
								}
							}
						}

						if(flag) {
							sameAccessoryflag = true;
						}
					}
				}

				if(samePropertyflag && sameAccessoryflag) {//表示属性和辅料都相同
					existCart = litemallCart;
					break;
				}
    		}
        }

        if (existCart == null) {
        	//验证商品原料是否充足
        	if(!isMerchandiseEnough(shopId, request)) {
        		//原料不足
        		return ResponseUtil.fail(WxResponseEnum.GOODS_MERCHANDISE_NOTENOUGH);
        	}

        	LitemallCart cart = new LitemallCart();
        	cart.setUserId(userId);
        	cart.setShopId(shopId);
	    	LitemallShop shop = litemallShopService.findById(cart.getShopId());
	        cart.setShopName(shop.getName());
        	cart.setGoodsId(goodsId);
        	cart.setGoodsSn(goods.getGoodsSn());
        	cart.setGoodsName((goods.getName()));
        	cart.setPicUrl(goods.getPicUrl());
        	cart.setNumber(number.shortValue());

        	//设置规格值
        	BigDecimal sellPrice = BigDecimal.ZERO;
            List<String> specifications = new ArrayList<>();
            //规格价格
            if(null != specIds && specIds.length > 0 ){
            	cart.setSpecificationIds(specIds);
                List<LitemallGoodsSpecification> litemallGoodsSpecifications = specificationService.queryByIds(specIds);
                for(LitemallGoodsSpecification item : litemallGoodsSpecifications){
                    sellPrice = sellPrice.add(item.getPrice());
                    specifications.add(item.getSpecification());
                }
                cart.setSpecifications(specifications.toArray(new String[]{}));
            }
            BigDecimal goodsPrice = sellPrice;

            //购物车辅料
            List<LitemallCartGoodsAccessory> cartGoodsAccessories = new ArrayList<>();
            List<CartAddAccessoryVo> accessoryList = request.getAccessoryList();
            if(!CollectionUtils.isEmpty(accessoryList)){
            	//创建辅料价格临时变量
        		BigDecimal accessoryPrice = BigDecimal.ZERO;
        		for (CartAddAccessoryVo cartAddAccessoryVo : accessoryList) {
        			Integer accessoryId = cartAddAccessoryVo.getAccessoryId();
        			LitemallGoodsAccessory accessory = litemallGoodsAccessoryService.findById(accessoryId);
        			//判断辅料是否充足
        			LitemallShopMerchandise merchandise = litemallShopMerchandiseService.queryByMerIdAndShopId(accessory.getMerchandiseId(), shopId);
                    if (merchandise == null || merchandise.getBasicNumber()< cartAddAccessoryVo.getNumber() * number) {
                        return ResponseUtil.fail(WxResponseEnum.ACCESSORY_ENOUGH);
                    }

        			LitemallCartGoodsAccessory cartGoodsAccessory = new LitemallCartGoodsAccessory();
        			cartGoodsAccessory.setGoodsId(goodsId);
        			cartGoodsAccessory.setAccessoryId(accessoryId);
        			Integer accessoryNumber = cartAddAccessoryVo.getNumber();
        			cartGoodsAccessory.setNumber(accessoryNumber);

        			Integer costType = accessory.getCostType();
        			if(Constants.ACCESSORY_COST_TYPE_TIME == costType) {//按次计费只需增加一次费用
        				cartGoodsAccessory.setPrice(accessory.getPrice());
        			}else {//按份计算
        				if(accessoryNumber>0) {
        					cartGoodsAccessory.setPrice(accessory.getPrice().multiply(new BigDecimal(accessoryNumber)));
        				}else {
        					cartGoodsAccessory.setPrice(accessory.getPrice());
        				}
        			}
        			cartGoodsAccessories.add(cartGoodsAccessory);

        			accessoryPrice = accessoryPrice.add(cartGoodsAccessory.getPrice());
        		}
        		sellPrice = sellPrice.add(accessoryPrice);
            }
            cart.setPrice(sellPrice);
            List<LitemallGoodsProduct> products = productService.queryByGidAndSid(request.getGoodsId(),request.getShopId());
            if(goods.getType() == 1 && products.size() == 0){
//                cart.setProductId(products.get(0).getId());
                return ResponseUtil.fail(GOODS_NO_STOCK,"库存不足");
            }else{
                if(products.size() == 0){
                    products = productService.queryByGidAndSid(request.getGoodsId(),null);

                    if(products.size() >0){
                        cart.setProductId(products.get(0).getId());
                    }else{
                        return ResponseUtil.fail(GOODS_NO_STOCK,"库存不足");
                    }
                }
            }

            cart.setChecked(true);
            cart.setGoodsPrice(goodsPrice);
            cartService.add(cart);
            for(LitemallCartGoodsAccessory item : cartGoodsAccessories) {
                item.setCartId(cart.getId());
                litemallCartGoodsAccessoryService.add(item);
            }

            //保存商品属性
        	List<CartAddPropertyVo> propertyList = request.getPropertyList();
        	if(!CollectionUtils.isEmpty(propertyList)) {
        		for (CartAddPropertyVo cartAddPropertyVo : propertyList) {
        			LitemallCartGoodsProperty litemallCartGoodsProperty = new LitemallCartGoodsProperty();
        			BeanUtils.copyProperties(cartAddPropertyVo, litemallCartGoodsProperty);
        			litemallCartGoodsProperty.setCartId(cart.getId());
        			litemallCartGoodsProperty.setGoodsId(goodsId);

        			litemallCartGoodsPropertyService.add(litemallCartGoodsProperty);
    			}
        	}
        } else {
            //取得规格的信息,判断规格库存
            int num = existCart.getNumber() + number;
            List<CartAddAccessoryVo> accessoryList = request.getAccessoryList();
            if(!CollectionUtils.isEmpty(accessoryList)){
                for (CartAddAccessoryVo item : accessoryList) {
                    LitemallGoodsAccessory accessory = litemallGoodsAccessoryService.findById(item.getAccessoryId());
                    LitemallShopMerchandise merchandise = litemallShopMerchandiseService.queryByMerIdAndShopId(accessory.getMerchandiseId(), shopId);
                    if (merchandise == null || merchandise.getBasicNumber()< item.getNumber() * number) {
                        return ResponseUtil.fail(WxResponseEnum.ACCESSORY_ENOUGH);
                    }
                }
            }
            existCart.setNumber((short) num);
            if (cartService.updateById2(existCart) == 0) {
                return ResponseUtil.updatedDataFailed();
            }
        }

        return goodscount(userId);
    }*/


    /**
     * 保存编辑购物车
     *
     * @param request 请求
     * @return {@link Object}
     */
    public Object saveEditCart(CartAddRequest request) {
        if (request == null) {
            return ResponseUtil.badArgument();
        }
        Integer shopId = request.getShopId();
        Integer number = request.getNumber();
        Integer goodsId = request.getGoodsId();
        Integer[] specIds = request.getSpecIds();
        if (!ObjectUtils.allNotNull(number, goodsId, shopId)) {
            return ResponseUtil.badArgument();
        }
        if(number <= 0){
            return ResponseUtil.badArgument();
        }

        //判断商品是否可以购买
        LitemallGoods goods = goodsService.findById(goodsId);
        if (goods == null || !goods.getIsOnSale()) {
            return ResponseUtil.fail(GOODS_UNSHELVE, "商品已下架");
        }
        //得到购物车商品
        LitemallCart cart = litemallCartService.findById(request.getId());
        cart.setSpecificationIds(request.getSpecIds());

        //编辑购物车辅料表信息
        //删除之前的辅料信息
        litemallCartGoodsAccessoryService.deleteByCartId(request.getId());

        //删除之前属性表信息
        litemallCartGoodsPropertyService.remove(Wrappers.lambdaQuery(LitemallCartGoodsProperty.class).eq(LitemallCartGoodsProperty::getCartId,request.getId()));


        //添加新的
        //判断购物车中是否存在此规格辅料相同的商品
        LitemallCart existCart = null;
        List<LitemallCart> existCartLs = cartService.queryByGidAndUidAndSpecIdsAndCartId(goodsId, cart.getUserId(), specIds,shopId,cart.getId());
        if(!CollectionUtils.isEmpty(existCartLs)) {
            //获得添加的辅料列表
            List<CartAddAccessoryVo> accessoryParam = request.getAccessoryList();
            int accessorySize = accessoryParam != null? accessoryParam.size():0;
            //获得添加的属性列表
            List<CartAddPropertyVo> propertyParam = request.getPropertyList();
            int propertySize = propertyParam != null? propertyParam.size():0;
            for (LitemallCart litemallCart : existCartLs) {
                Integer cartId = litemallCart.getId();

                boolean samePropertyflag = false;//设置请求添加的商品与该订单商品属性相同标志
                if( propertySize ==  litemallCartGoodsPropertyService.countByCartId(cartId).intValue()) {
                    boolean flag = true;

                    if(propertySize > 0) {
                        for (CartAddPropertyVo cartAddPropertyVo : propertyParam) {
                            LitemallCartGoodsProperty litemallCartGoodsProperty = litemallCartGoodsPropertyService.findByCartIdAndGoodsPropertyIdAndValue
                                    (cartId, cartAddPropertyVo.getGoodsPropertyId(), cartAddPropertyVo.getValue().trim());
                            if(null == litemallCartGoodsProperty) {
                                flag = false;
                                break;
                            }
                        }
                    }

                    if(flag) {
                        samePropertyflag = true;
                    }
                }

                boolean sameAccessoryflag = false;//设置请求添加的商品与该订单商品辅料相同标志
                if(samePropertyflag) {//说明属性值相同
                    if(litemallCartGoodsAccessoryService.countByCartId(litemallCart.getId()) == accessorySize) {
                        boolean flag = true;
                        if(accessorySize > 0) {
                            //单个判断
                            for(CartAddAccessoryVo item : accessoryParam){
                                if(!litemallCartGoodsAccessoryService.exist(litemallCart.getId(), item.getAccessoryId(), item.getNumber())){
                                    flag = false;
                                    break;
                                }
                            }
                        }

                        if(flag) {
                            sameAccessoryflag = true;
                        }
                    }
                }

                if(samePropertyflag && sameAccessoryflag) {//表示属性和辅料都相同
                    existCart = litemallCart;
                    break;
                }
            }
        }

        if (existCart == null) {
            //验证商品原料是否充足
            if(!isMerchandiseEnough(shopId, request)) {
                //原料不足
                return ResponseUtil.fail(WxResponseEnum.GOODS_MERCHANDISE_NOTENOUGH);
            }

            cart.setShopId(shopId);
            LitemallShop shop = litemallShopService.findById(cart.getShopId());
            cart.setShopName(shop.getName());
            cart.setGoodsId(goodsId);
            cart.setGoodsSn(goods.getGoodsSn());
            cart.setGoodsName((goods.getName()));
            cart.setPicUrl(goods.getPicUrl());
            cart.setNumber(number.shortValue());

            //设置规格值
            BigDecimal sellPrice = BigDecimal.ZERO;
            List<String> specifications = new ArrayList<>();
            //规格价格
            if(null != specIds && specIds.length > 0 ){
                cart.setSpecificationIds(specIds);
                List<LitemallGoodsSpecification> litemallGoodsSpecifications = specificationService.queryByIds(specIds);
                for(LitemallGoodsSpecification item : litemallGoodsSpecifications){
                    sellPrice = sellPrice.add(item.getPrice());
                    specifications.add(item.getSpecification());
                }
                cart.setSpecifications(specifications.toArray(new String[]{}));
            }
            BigDecimal goodsPrice = sellPrice;

            //购物车辅料
            List<LitemallCartGoodsAccessory> cartGoodsAccessories = new ArrayList<>();
            List<CartAddAccessoryVo> accessoryList = request.getAccessoryList();
            if(!CollectionUtils.isEmpty(accessoryList)){
                //创建辅料价格临时变量
                BigDecimal accessoryPrice = BigDecimal.ZERO;
                for (CartAddAccessoryVo cartAddAccessoryVo : accessoryList) {
                    Integer accessoryId = cartAddAccessoryVo.getAccessoryId();
                    LitemallGoodsAccessory accessory = litemallGoodsAccessoryService.findById(accessoryId);
                    //判断辅料是否充足
                    LitemallShopMerchandise merchandise = litemallShopMerchandiseService.queryByMerIdAndShopId(accessory.getMerchandiseId(), shopId);
                    if (merchandise == null || merchandise.getBasicNumber()< cartAddAccessoryVo.getNumber() * number) {
                        return ResponseUtil.fail(WxResponseEnum.ACCESSORY_ENOUGH);
                    }

                    LitemallCartGoodsAccessory cartGoodsAccessory = new LitemallCartGoodsAccessory();
                    cartGoodsAccessory.setGoodsId(goodsId);
                    cartGoodsAccessory.setAccessoryId(accessoryId);
                    Integer accessoryNumber = cartAddAccessoryVo.getNumber();
                    cartGoodsAccessory.setNumber(accessoryNumber);

                    Integer costType = accessory.getCostType();
                    if(Constants.ACCESSORY_COST_TYPE_TIME == costType) {//按次计费只需增加一次费用
                        cartGoodsAccessory.setPrice(accessory.getPrice());
                    }else {//按份计算
                        if(accessoryNumber>0) {
                            cartGoodsAccessory.setPrice(accessory.getPrice().multiply(new BigDecimal(accessoryNumber)));
                        }else {
                            cartGoodsAccessory.setPrice(accessory.getPrice());
                        }
                    }
                    cartGoodsAccessories.add(cartGoodsAccessory);

                    accessoryPrice = accessoryPrice.add(cartGoodsAccessory.getPrice());
                }
                sellPrice = sellPrice.add(accessoryPrice);
            }
            cart.setPrice(sellPrice);
            List<LitemallGoodsProduct> products = productService.queryByGidAndSid(request.getGoodsId(),request.getShopId());
            if(goods.getType() == 1 && products.size() == 0){
//                cart.setProductId(products.get(0).getId());
                return ResponseUtil.fail(GOODS_NO_STOCK,"库存不足");
            }else{
                if(products.size() == 0){
                    products = productService.queryByGidAndSid(request.getGoodsId(),null);

                    if(products.size() >0){
                        cart.setProductId(products.get(0).getId());
                    }else{
                        return ResponseUtil.fail(GOODS_NO_STOCK,"库存不足");
                    }
                }
            }

            cart.setChecked(true);
            cart.setGoodsPrice(goodsPrice);
            //保存编辑
            cartService.updateById2(cart);
            for(LitemallCartGoodsAccessory item : cartGoodsAccessories) {
                item.setCartId(cart.getId());
                litemallCartGoodsAccessoryService.add(item);
            }

            //保存商品属性
            List<CartAddPropertyVo> propertyList = request.getPropertyList();
            if(!CollectionUtils.isEmpty(propertyList)) {
                for (CartAddPropertyVo cartAddPropertyVo : propertyList) {
                    LitemallCartGoodsProperty litemallCartGoodsProperty = new LitemallCartGoodsProperty();
                    BeanUtils.copyProperties(cartAddPropertyVo, litemallCartGoodsProperty);
                    litemallCartGoodsProperty.setCartId(cart.getId());
                    litemallCartGoodsProperty.setGoodsId(goodsId);

                    litemallCartGoodsPropertyService.add(litemallCartGoodsProperty);
                }
            }
        } else {
            //取得规格的信息,判断规格库存
            int num = existCart.getNumber() + number;
            List<CartAddAccessoryVo> accessoryList = request.getAccessoryList();
            if(!CollectionUtils.isEmpty(accessoryList)){
                for (CartAddAccessoryVo item : accessoryList) {
                    LitemallGoodsAccessory accessory = litemallGoodsAccessoryService.findById(item.getAccessoryId());
                    LitemallShopMerchandise merchandise = litemallShopMerchandiseService.queryByMerIdAndShopId(accessory.getMerchandiseId(), shopId);
                    if (merchandise == null || merchandise.getBasicNumber()< item.getNumber() * number) {
                        return ResponseUtil.fail(WxResponseEnum.ACCESSORY_ENOUGH);
                    }
                }
            }
            existCart.setNumber((short) num);
            if (cartService.updateById2(existCart) == 0) {
                return ResponseUtil.updatedDataFailed();
            }
        }

        return goodscount(cart.getUserId());
    }

    /**
     * 验证添加的商品原料是否足够
     * @param shopId
     * @param request
     * @return
     */
    private Boolean isMerchandiseEnough(Integer shopId, CartAddRequest request) {
    	List<Integer> merchandiseIdLs = new ArrayList<>();

    	//查询规格原料
    	Integer[] specIds = request.getSpecIds();
    	for (Integer specId : specIds) {
    		List<LitemallGoodsSpecificationMerchandise> goodsSpecMerchandises = goodsSpecificationMerchandiseService.queryBySpecid(specId);
    		for (LitemallGoodsSpecificationMerchandise goodsSpecMerchandise : goodsSpecMerchandises) {
    			Integer merchandiseId = goodsSpecMerchandise.getMerchandiseId();
    			if(!merchandiseIdLs.contains(merchandiseId)) {
    				merchandiseIdLs.add(merchandiseId);
    			}
    		}
		}

		//查询辅料原料
		List<CartAddAccessoryVo> accessoryList = request.getAccessoryList();
		if(!CollectionUtils.isEmpty(accessoryList)) {
			for (CartAddAccessoryVo accessoryVo : accessoryList) {
				LitemallGoodsAccessory accessory = litemallGoodsAccessoryService.findById(accessoryVo.getAccessoryId());
				Integer merchandiseId = accessory.getMerchandiseId();
				if(!merchandiseIdLs.contains(merchandiseId)) {
					merchandiseIdLs.add(merchandiseId);
				}
			}
		}

		for (Integer merchandiseId : merchandiseIdLs) {
			LitemallShopMerchandise litemallShopMerchandise = litemallShopMerchandiseService.queryByMerIdAndShopId(merchandiseId, shopId);
			if(null == litemallShopMerchandise) {
				return false;
			}
		}
		return true;
    }

    /**
     * 修改购物车商品货品数量
     *
     * @param userId 用户ID
     * @param cart   购物车商品信息， { id: xxx, goodsId: xxx, productId: xxx, number: xxx }
     * @return 修改结果
     */
    public Object update(Integer userId, LitemallCart cart) {
        if (cart == null) {
            return ResponseUtil.badArgument();
        }
        Integer productId = cart.getProductId();
        Integer number = cart.getNumber().intValue();
        Integer goodsId = cart.getGoodsId();
        Integer id = cart.getId();
        if (!ObjectUtils.allNotNull(id, productId, number, goodsId)) {
            return ResponseUtil.badArgument();
        }
        if(number <= 0){
            return ResponseUtil.badArgument();
        }

        //判断是否存在该订单
        // 如果不存在，直接返回错误
        LitemallCart existCart = cartService.findById(id);
        if (existCart == null) {
            return ResponseUtil.badArgumentValue();
        }

        // 判断goodsId和productId是否与当前cart里的值一致
        if (!existCart.getGoodsId().equals(goodsId)) {
            return ResponseUtil.badArgumentValue();
        }
        if (!existCart.getProductId().equals(productId)) {
            return ResponseUtil.badArgumentValue();
        }

        //判断商品是否可以购买
        LitemallGoods goods = goodsService.findById(goodsId);
        if (goods == null || !goods.getIsOnSale()) {
            return ResponseUtil.fail(GOODS_UNSHELVE, "商品已下架");
        }

        //取得规格的信息,判断规格库存
        LitemallGoodsProduct product = productService.findById(productId);
        if ( goods.getType() == 1 && product == null) {
            return ResponseUtil.fail(GOODS_NO_STOCK, "库存不足");
        }

        existCart.setNumber(number.shortValue());
        if (cartService.updateById2(existCart) == 0) {
            return ResponseUtil.updatedDataFailed();
        }
        return ResponseUtil.ok();
    }

    /**
     * 修改购物车商品货品数量
     *
     * @param userId 用户ID
     * @param request   购物车商品信息， { id: xxx, goodsId: xxx, productId: xxx, number: xxx }
     * @return 修改结果
     */
    public Response<Object> update(Integer userId, CartUpdateRequest request) {
    	if (request == null) {
    		return ResponseUtil.badArgument();
    	}
    	Integer number = request.getNumber();
    	Integer goodsId = request.getGoodsId();
    	Integer id = request.getCartId();
    	if (!ObjectUtils.allNotNull(id, number, goodsId)) {
    		return ResponseUtil.badArgument();
    	}
    	if(number <= 0){
    		return ResponseUtil.badArgument();
    	}

    	//判断是否存在该订单
    	// 如果不存在，直接返回错误
    	LitemallCart existCart = cartService.findById(id);
    	if (existCart == null) {
    		return ResponseUtil.badArgumentValue();
    	}

    	// 判断goodsId和productId是否与当前cart里的值一致
    	if (!existCart.getGoodsId().equals(goodsId)) {
    		return ResponseUtil.badArgumentValue();
    	}
    	//判断商品是否可以购买
    	LitemallGoods goods = goodsService.findById(goodsId);
    	if (goods == null || !goods.getIsOnSale()) {
    		return ResponseUtil.fail(GOODS_UNSHELVE, "商品已下架");
    	}

    	existCart.setNumber(number.shortValue());
    	if (cartService.updateById2(existCart) == 0) {
    		return ResponseUtil.updatedDataFailed();
    	}
    	return ResponseUtil.ok();
    }

    /**
     * 购物车商品货品勾选状态
     * <p>
     * 如果原来没有勾选，则设置勾选状态；如果商品已经勾选，则设置非勾选状态。
     *
     * @param userId 用户ID
     * @param body   购物车商品信息， { productIds: xxx, isChecked: 1/0 }
     * @return 购物车信息
     */
    /*public Response<CartIndexResponse> checked(Integer userId, String body) {
        if (body == null) {
            return ResponseUtil.badArgument();
        }

        List<Integer> cartIds = JacksonUtil.parseIntegerList(body, "cartIds");
        if (cartIds == null) {
            return ResponseUtil.badArgument();
        }

        Integer checkValue = JacksonUtil.parseInteger(body, "isChecked");
        if (checkValue == null) {
            return ResponseUtil.badArgument();
        }
        Boolean isChecked = (checkValue == 1);

        cartService.updateCheck(userId, cartIds, isChecked);
        return index(userId,null);
    }*/



    /**
     * 购物车商品货品数量
     * <p>
     * 如果用户没有登录，则返回空数据。
     *
     * @param userId 用户ID
     * @return 购物车商品货品数量
     */
    public Object goodscount(Integer userId) {
        if (userId == null) {
            return ResponseUtil.ok(0);
        }

        int goodsCount = 0;
        List<LitemallCart> cartList = cartService.queryByUid(userId);
        for (LitemallCart cart : cartList) {
            goodsCount += cart.getNumber();
        }

        return ResponseUtil.ok(goodsCount);
    }

    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }

        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        return date.after(begin) && date.before(end);
    }

    private boolean shopCheckWeeksTime(LitemallShop shop){
        // 假设门店的营业时间已经存在于 shop.getWeeksTime() 集合中
        List<LocalTime[]> weeksTime = shop.getWeeksTime();
        if(weeksTime==null){return false;}
        // 获取当前日期和时间
        LocalDate currentDate = LocalDate.now();
        LocalTime currentTime = LocalTime.now();

        if(StrUtil.isNotEmpty(shop.getTimezone())){
            // 设置选择的时区
            ZoneId zoneId = ZoneId.of(shop.getTimezone());
            // 获取当前日期
            currentDate = LocalDate.now(zoneId);
            // 获取当前时间
            currentTime = LocalTime.now(zoneId);
        }
        // 获取当前是星期几
        DayOfWeek currentDayOfWeek = currentDate.getDayOfWeek();

        // 获取对应的门店营业时间
        LocalTime[] businessHours = weeksTime.get(currentDayOfWeek.getValue() - 1);

        // 判断当前时间是否处于门店的开业时间范围内
        boolean isOpen = currentTime.isAfter(businessHours[0]) && currentTime.isBefore(businessHours[1]);

        List<AdminShopSpecialDateDTO> specialDateList = shop.getSpecial()==null?CollUtil.newArrayList():shop.getSpecial(); // 假设您已经有了AdminShopSpecialDateDTO的集合
        LocalDate today = LocalDate.now();
        // 遍历集合中的每个AdminShopSpecialDateDTO对象
        for (AdminShopSpecialDateDTO dto : specialDateList) {
            LocalDate specialDate = dto.getSpecialDate();
            LocalTime[] specialTime = dto.getSpecialTime();

            // 在这里进行特定逻辑处理，判断门店是否营业
            // 判断specialDate是否是今天
            if (!specialDate.isEqual(today)) {
                continue;
            }
            // 判断当前时间是否在营业时间范围内
            isOpen = currentTime.isAfter(specialTime[0]) && currentTime.isBefore(specialTime[1]);
        }
        return isOpen;
    }

    /**
     * 购物车下单
     *
     * GST：联邦商品服务税（Goods and Service Tax）
     * PST：省级消费税（Provincial Sales Tax）
     * HST：合并销售税（Harmonized Sales Tax）
     *
     * GST和PST从字面意义上很好理解，分别是联邦和省向消费者征收的消费税。
     * HST则代表上述两种税的合并，由政府统一征收，但只有某一些省份适用（不包括BC省）。
     */
    //算账
    @SneakyThrows
    public Response<CartCheckOutResponse> checkout(Integer userId, CartCheckOutRequest cartCheckOutRequest) {

        //判断该门店是否歇业
        LitemallShop litemallShop = litemallShopService.findById(cartCheckOutRequest.getShopId());
        //动态设置门店时区
        dynamicTimeZoneConfiguration.setDynamicTimeZone(litemallShop.getTimezone());
        if (!shopCheckWeeksTime(litemallShop)) {
            return ResponseUtil.fail(8008,"门店已歇业，请营业再来吧");
        }

        Integer couponId = cartCheckOutRequest.getCouponId();
        Integer addressId = cartCheckOutRequest.getAddressId();
        Integer shopId = cartCheckOutRequest.getShopId();

        // 收货地址
        LitemallAddress checkedAddress = null;
        if (addressId == null || addressId.equals(0)) {
            //根据用户ID找收货地址
            checkedAddress = addressService.findDefault(userId);
            // 如果仍然没有地址，则是没有收获地址
            // 返回一个空的地址id=0，这样前端则会提醒添加地址
            if (checkedAddress == null) {
                checkedAddress = new LitemallAddress();
                checkedAddress.setId(0);
                addressId = 0;
            } else {
                addressId = checkedAddress.getId();
            }
        } else {
            checkedAddress = addressService.query(userId, addressId);
            // 如果null, 则报错
            if (checkedAddress == null) {
                return ResponseUtil.badArgumentValue();
            }
        }


        // 商品价格
        //拿到购物车id集合
        //List<Integer> cartIds = cartCheckOutRequest.getCartIds();
        //购物车下单店铺商品信息类
        List<CartCheckOutGoodsInfoVo> checkedGoodsList = new ArrayList<>();
        //购物车商品表
        List<LitemallCart> litemallCarts = new ArrayList<>();

        /*if (cartIds == null || cartIds.size() == 0 ) {
            //如果没有选购商品就去找用户购物车里选中的
            litemallCarts = cartService.queryByUidAndChecked(userId);
        } else {
            litemallCarts = cartService.findByIds(cartIds);
        }*/

        for(LitemallCart cart : litemallCarts){
        	CartCheckOutGoodsInfoVo vo = new CartCheckOutGoodsInfoVo();
            BeanUtils.copyProperties(cart, vo);
            vo.setPrice(vo.getPrice().setScale(2));
            checkedGoodsList.add(vo);
        }

        //Map<String,Object> rtn = new HashMap<>();
        List<CartCheckOutShopOrderVo> list = new ArrayList<>();
        List<Integer> shopIds = checkedGoodsList.stream()
                .map(CartCheckOutGoodsInfoVo::getShopId)
                .collect(Collectors.toList());
        List<LitemallShop> shops = litemallShopService.getByIds(shopIds);

        Map<LitemallShop, List<CartCheckOutGoodsInfoVo>> groupShop = checkedGoodsList.stream()
                .collect(Collectors.groupingBy(cart -> shops.stream().findFirst().get(), Collectors.toList()));
        //获取所有订单总价、税收总价

        BigDecimal totalPrice = new BigDecimal(0.00);
        BigDecimal totalTaxPrice = new BigDecimal(0.00);

        BigDecimal totalGSTPrice = new BigDecimal(0.00);
        BigDecimal totalPSTPrice = new BigDecimal(0.00);
        BigDecimal totalHSTPrice = new BigDecimal(0.00);

        //bbb
        Set<Map.Entry<LitemallShop, List<CartCheckOutGoodsInfoVo>>> entries = groupShop.entrySet();
        Iterator<Map.Entry<LitemallShop, List<CartCheckOutGoodsInfoVo>>> iterator = entries.iterator();
        BigDecimal memberPrice = new BigDecimal(0);
        List<LumierePayMemberUser> payMemberUsers = payMemberUserService.listMemberByUserId(userId);
        //会员的倍率
        Integer cityRegionId = getShopRegionId(shopId);
        BigDecimal memberPer = new BigDecimal(0);

        //优惠来源
        List<WxMemberSourceDTO> wxMemberSourceVOList = CollUtil.newArrayList();

        Boolean notOverlay = false;
        BigDecimal maxMemberPer = new BigDecimal(0);
        //叠加付费会员优惠比例
        for(LumierePayMemberUser payMemberUser : payMemberUsers){
            //获得付费会员
            LumierePayMember payMember = lumierePayMemberService.findById(payMemberUser.getPayMemberId());
            //判断可以在该店使用
            Boolean result = payMember.getShopIds()!=null?ArrayUtil.contains(payMember.getShopIds(), cityRegionId):true;
            //当付费会员允许 汇率叠加
            if(payMember.getIsOverlay()==1 && result &&payMember.getDicountPer() != null){
                memberPer=memberPer.add((payMember.getDicountPer().divide(new BigDecimal(100)))).setScale(2, BigDecimal.ROUND_HALF_UP);
                //会员优惠来源
                wxMemberSourceVOList.add(new WxMemberSourceDTO(payMember.getDicountPer().divide(new BigDecimal(100)),payMember.getName()));
                notOverlay=true;
            }
            //选择一个最高的会员优惠率
            if(payMember.getDicountPer()!=null&&(memberPer.compareTo(payMember.getDicountPer())==-1)){
                maxMemberPer=payMember.getDicountPer();
            }
        }
        //如果没有一个会员叠加，则选择一个最高的会员优惠率
        memberPer=notOverlay==false?maxMemberPer.divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP):memberPer;

        while(iterator.hasNext()){
            Map.Entry<LitemallShop, List<CartCheckOutGoodsInfoVo>> i = iterator.next();
            LitemallShop shop = i.getKey();

            if(shop.getTypes() != null){
                Arrays.sort(shop.getTypes(), (o1,  o2)->o1 - o2);
            }

            List<CartCheckOutGoodsInfoVo> carts = i.getValue();
            /**
             * 税费和总价
             */
            //BigDecimal taxPrice = new BigDecimal(0.00);
            BigDecimal checkedGoodsPrice = new BigDecimal(0.00);

            //税率代码(GST、PST、HST) 税收值 单次计算
            BigDecimal GSTPrice = new BigDecimal(0.00);
            BigDecimal PSTPrice = new BigDecimal(0.00);
            BigDecimal HSTPrice = new BigDecimal(0.00);

            for (CartCheckOutGoodsInfoVo cart : carts) {
                cart.setSpecificationList(new ArrayList<>());
//                cart.setAccessories(new ArrayList<>());
                /**
                 * 规格价格
                 */
                //BigDecimal specGoodsPrice = new BigDecimal(0.00);
                if(cart.getSpecificationIds() != null && cart.getSpecificationIds().length > 0){
                    for(Integer sid : cart.getSpecificationIds()){
                        LitemallGoodsSpecification specificationServiceById = specificationService.findById(sid);
                        if(specificationServiceById != null){
                        	SpecificationVo specificationVo = new SpecificationVo();
                        	BeanUtils.copyProperties(specificationServiceById, specificationVo);
                            cart.getSpecificationList().add(specificationVo);
                            //specGoodsPrice = specGoodsPrice.add(specificationServiceById.getPrice().multiply(new BigDecimal(cart.getNumber())));
                        }
                    }
                }
                /**
                 * 辅料价格
                 */
                //BigDecimal acceGoodsPrice = new BigDecimal(0.00);
                List<LitemallCartGoodsAccessory> accessories = litemallCartGoodsAccessoryService.queryByCartId(cart.getId());
                if(accessories != null){

                    List<AccessoryVo> collect = accessories.stream().map(item -> {
                        LitemallGoodsAccessory accessory = litemallGoodsAccessoryService.findById(item.getAccessoryId());
                        AccessoryVo accessoryVo = new AccessoryVo();
                        BeanUtils.copyProperties(accessory, accessoryVo);
                        accessoryVo.setSelectNum(item.getNumber());
                        return accessoryVo;
                    }).collect(Collectors.toList());
                    cart.setAccessories(collect);
                }
                checkedGoodsPrice = checkedGoodsPrice.add(cart.getPrice().multiply(new BigDecimal(cart.getNumber())));


            	List<LitemallCartGoodsProperty> propertyList = litemallCartGoodsPropertyService.queryByCartId(cart.getId());
                if(!CollectionUtils.isEmpty(propertyList)) {
                	List<PropertyVo> collect = propertyList.stream().map(item -> {
                		LitemallGoodsProperty litemallGoodsProperty = litemallGoodsPropertyService.findById(item.getGoodsPropertyId());
                		PropertyVo propVo = new PropertyVo();
                        BeanUtils.copyProperties(litemallGoodsProperty, propVo);
                        propVo.setSelectValue(item.getValue());
                        return propVo;
                    }).collect(Collectors.toList());
                	cart.setPropList(collect);
                }
            }

            BigDecimal nowPrice = checkedGoodsPrice;
            if(memberPer.compareTo(new BigDecimal(1))  != 0 ){
                memberPrice = checkedGoodsPrice.compareTo(checkedGoodsPrice.multiply(memberPer)) >= 0?checkedGoodsPrice.multiply(memberPer) : checkedGoodsPrice ;
            }
            checkedGoodsPrice = nowPrice.subtract(memberPrice);
            nowPrice = null;

            // 计算优惠券可用情况
            BigDecimal tmpCouponPrice = new BigDecimal(0.00);
            //Integer tmpCouponId = 0;

            /*// 获取优惠券减免金额，优惠券可用数量
            List<LumiereCouponUser> lumiereCouponUsers = lumiereCouponUserService.list(Wrappers.lambdaQuery(LumiereCouponUser.class)
                    .eq(LumiereCouponUser::getUserId, userId));
            int availableCouponLength =couponVerifyService.checkCouponStrategy(lumiereCouponUsers, checkedGoodsPrice,1,shopId,litemallCarts.stream().map(LitemallCart::getGoodsId).distinct().collect(Collectors.toList())).size();
*/
            //实际的订单费用
            BigDecimal actualGoodsPrice = checkedGoodsPrice.subtract(tmpCouponPrice);
            actualGoodsPrice = actualGoodsPrice.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : actualGoodsPrice;

            //税费计算  税费 = 商品价格 * 商品数量 * 税率
            for (CartCheckOutGoodsInfoVo cart : carts) {
                /**
                 * 获取商品选用税费
                 */
            	LitemallGoodsRegion goodRegion = goodsRegionService.findByGidAndCityId(cart.getGoodsId(), cityRegionId);
            	if(null == goodRegion) {
            		return ResponseUtil.fail(GOODS_SHOP_INVALID, "商品不属于该店铺区域");
            	}
                //税率类型(税率表id数组)
            	Integer[] taxTypes = goodRegion.getTaxTypes();

            	//购物车该条记录的商品费用
//            	BigDecimal cartGoodsPrice = cart.getPrice().multiply(new BigDecimal(cart.getNumber()));
            	//优惠后商品单价
//            	BigDecimal afterDiscountPrice = cart.getPrice().multiply(actualGoodsPrice).divide(checkedGoodsPrice).setScale(2, BigDecimal.ROUND_HALF_UP);
            	BigDecimal afterDiscountPrice = checkedGoodsPrice.compareTo(BigDecimal.ZERO) > 0 ? cart.getPrice().multiply(new BigDecimal(1).subtract(memberPer)).multiply(actualGoodsPrice).divide(checkedGoodsPrice, 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO;
            	BigDecimal afterDiscountGoodsPrice = afterDiscountPrice.multiply(new BigDecimal(cart.getNumber()));

            	for (Integer taxType : taxTypes) {
        			LitemallTax litemallTax = litemallTaxService.findById(taxType);
        			if(null == litemallTax) {
        				return ResponseUtil.fail(TAX_NOT_EXIST, "商品在该店铺区域设置的税费类型不存在");
        			}else if(litemallTax.getDeleted() || (!litemallTax.getEnable())) {
        				continue;
        			}
        			BigDecimal value = litemallTax.getValue();
                    switch (litemallTax.getCode()){
                        case "GST":
                             GSTPrice=afterDiscountGoodsPrice.compareTo(BigDecimal.ZERO) > 0 ? GSTPrice.add(afterDiscountGoodsPrice.multiply(value).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP)) : BigDecimal.ZERO;
                             break;
                        case "HST":
                             HSTPrice=afterDiscountGoodsPrice.compareTo(BigDecimal.ZERO) > 0 ? HSTPrice.add(afterDiscountGoodsPrice.multiply(value).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP)) : BigDecimal.ZERO;
                             break;
                        //要么是 PST
                        default:
                            PSTPrice=afterDiscountGoodsPrice.compareTo(BigDecimal.ZERO) > 0 ? PSTPrice.add(afterDiscountGoodsPrice.multiply(value).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP)) : BigDecimal.ZERO;
                    }
        			//获取税收值
        			//taxPrice = afterDiscountGoodsPrice.compareTo(BigDecimal.ZERO) > 0 ? taxPrice.add(afterDiscountGoodsPrice.multiply(value).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP)) : BigDecimal.ZERO;
        		}
            }

            // 根据订单商品总价计算运费，满88则免运费，否则8元；
            BigDecimal freightPrice = new BigDecimal(0.00);
            if (checkedGoodsPrice.compareTo(SystemConfig.getFreightLimit()) < 0) {
                freightPrice = SystemConfig.getFreight();
            }

            //总税费
            totalTaxPrice = totalTaxPrice.add(GSTPrice.add(PSTPrice).add(HSTPrice));

            // 订单费用
            BigDecimal orderTotalPrice = checkedGoodsPrice.max(new BigDecimal(0.00)).add(totalTaxPrice).add(freightPrice);
            // 获取优惠券减免金额，优惠券可用数量
            List<LumiereCouponUser> lumiereCouponUsers = lumiereCouponUserService.list(Wrappers.lambdaQuery(LumiereCouponUser.class)
                    .eq(LumiereCouponUser::getUserId, userId));
            int availableCouponLength =couponVerifyService.checkCouponStrategy(lumiereCouponUsers, checkedGoodsPrice,1,shopId,litemallCarts.stream().map(LitemallCart::getGoodsId).distinct().collect(Collectors.toList())).size();

            //订单费用减去优惠券价格
            BigDecimal actualPrice = orderTotalPrice.subtract(tmpCouponPrice);
            //添加到总价
            totalPrice = totalPrice.add(actualPrice);

            //totalTaxPrice = totalTaxPrice.add(taxPrice);

            //税率代码(GST、PST、HST) 税收值 合计
            totalGSTPrice = totalGSTPrice.add(GSTPrice);
            totalPSTPrice = totalPSTPrice.add(PSTPrice);
            totalHSTPrice = totalHSTPrice.add(HSTPrice);

            CartCheckOutShopOrderVo cartCheckOutShopOrderVo = new CartCheckOutShopOrderVo();
            cartCheckOutShopOrderVo.setAvailableCouponLength(00);
            cartCheckOutShopOrderVo.setShopGoodsTotalPrice(checkedGoodsPrice);
            cartCheckOutShopOrderVo.setShopOrderTotalPrice(orderTotalPrice);
            cartCheckOutShopOrderVo.setShopActualPrice(actualPrice);
            cartCheckOutShopOrderVo.setShopCheckedGoodsList(checkedGoodsList);
            cartCheckOutShopOrderVo.setShopTaxTotalPrice(GSTPrice.add(PSTPrice).add(HSTPrice));

            //税率代码(GST、PST、HST) 税收值 单计
            cartCheckOutShopOrderVo.setGSTPrice(GSTPrice);
            cartCheckOutShopOrderVo.setPSTPrice(PSTPrice);
            cartCheckOutShopOrderVo.setHSTPrice(HSTPrice);

            cartCheckOutShopOrderVo.setShopFreightPrice(freightPrice);
            cartCheckOutShopOrderVo.setShopCouponPrice(new BigDecimal(0.00));
            cartCheckOutShopOrderVo.setShopCouponId(couponId);
            cartCheckOutShopOrderVo.setCouponPrice(tmpCouponPrice);
            CartCheckOutShopVo shopVo = new CartCheckOutShopVo();
            BeanUtils.copyProperties(shop, shopVo);
            cartCheckOutShopOrderVo.setShop(shopVo);

            list.add(cartCheckOutShopOrderVo);
        }

        CartCheckOutResponse response = new CartCheckOutResponse();
        CartCheckOutAddressVo cartCheckOutAddressVo = new CartCheckOutAddressVo();
        BeanUtils.copyProperties(checkedAddress, cartCheckOutAddressVo);
        response.setCheckedAddress(cartCheckOutAddressVo);
        response.setOrderTotalPrice(totalPrice.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : totalPrice.add(memberPrice));
        response.setTaxTotalPrice(totalTaxPrice.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : totalTaxPrice);
        //税率代码(GST、PST、HST) 税收值 合计
        response.setTotalGSTPrice(totalGSTPrice);
        response.setTotalPSTPrice(totalPSTPrice);
        response.setTotalHSTPrice(totalHSTPrice);

        response.setList(list);
        response.setMemberPrice(memberPrice);

        response.setMemberPer(memberPer);
        response.setWxMemberSourceVOList(wxMemberSourceVOList);

        return ResponseUtil.ok(response);
    }



    /**
     * 获取店铺的地区id
     * @param shopId
     */
    private Integer getShopRegionId(Integer shopId) {
    	List<LitemallShopRegion> litemallShopRegions = shopRegionService.queryByShopId(shopId);
    	if(!CollectionUtils.isEmpty(litemallShopRegions)) {
			for (LitemallShopRegion litemallShopRegion : litemallShopRegions) {
				LitemallRegion litemallRegion = regionService.findById(litemallShopRegion.getRegionId());
				if(Constants.REGION_TYPE_CITY == litemallRegion.getType()) {
					return litemallShopRegion.getRegionId();
				}
			}
		}
    	return null;
    }



    /**
     * 切换门店，修改购物车信息
     * @param userId
     * @return
     */
    public Object changeShop(Integer userId, Integer shopId) {

        List<LitemallCart> litemallCarts = cartService.queryByUid(userId);
        for(LitemallCart cart : litemallCarts){
            if(cart.getShopId() != shopId){
//                List<LitemallGoodsProduct> products = litemallGoodsProductService.queryByGidAndSid(cart.getGoodsId(), shopId);
                //*
                 //* 这里如果要切换的门店没有该商品，则将购物车的productId置为null，前端则不可结算该商品

//                if(products.size()>0){
                if(hasGoods(cart.getGoodsId(), shopId)){
//                    BigDecimal sellPrice = product.getSellPrice();
                	//如果是店铺商品，则判断该商品是否属于该店铺，如果是总部商品则判断该商品是否在店铺区域内


                    BigDecimal sellPrice = BigDecimal.ZERO;
                    //规格价格
                    if(null != cart.getSpecificationIds() && cart.getSpecificationIds().length > 0 ){
                        List<LitemallGoodsSpecification> litemallGoodsSpecifications = specificationService.queryByIds(cart.getSpecificationIds());
                        for(LitemallGoodsSpecification item : litemallGoodsSpecifications){
                            sellPrice = sellPrice.add(item.getPrice());
                        }
                    }
                    BigDecimal goodsPrice = sellPrice;

                    //创建辅料价格临时变量
                    List<LitemallCartGoodsAccessory> cartGoodsAccessories = litemallCartGoodsAccessoryService.queryByCartId(cart.getId());
                    if(cartGoodsAccessories != null && cartGoodsAccessories.size() > 0){
                    	BigDecimal accessoryPrice = BigDecimal.ZERO;
                        for(LitemallCartGoodsAccessory item : cartGoodsAccessories){
                            LitemallGoodsAccessory accessory = litemallGoodsAccessoryService.findById(item.getAccessoryId());
                            LitemallShopMerchandise merchandise = litemallShopMerchandiseService.queryByMerIdAndShopId(accessory.getMerchandiseId(), shopId);
                            if(merchandise == null || merchandise.getNumber() < item.getNumber() * cart.getNumber()){
                                return ResponseUtil.fail(WxResponseEnum.ACCESSORY_ENOUGH);
                            }

                            Integer accessoryNumber = item.getNumber();
                            Integer costType = accessory.getCostType();
                			if(Constants.ACCESSORY_COST_TYPE_TIME == costType) {//按次计费只需增加一次费用
                				accessoryPrice.add(accessory.getPrice());
                			}else {//按份计算
                				if(accessoryNumber>0) {
                					accessoryPrice.add(accessory.getPrice().multiply(new BigDecimal(accessoryNumber)));
                				}else {
                					accessoryPrice.add(accessory.getPrice());
                				}
                			}
                        }
                        sellPrice = sellPrice.add(accessoryPrice);
                    }
                    LitemallCart update = new LitemallCart();
                    update.setPrice(sellPrice);
                    update.setGoodsPrice(goodsPrice);
                    update.setShopId(shopId);
//                    update.setProductId(product.getId());
                    update.setId(cart.getId());
                    cartService.updateById(update);
                }else{
                    LitemallCart update = new LitemallCart();
                    update.setShopId(0);
//                    update.setProductId(0);
                    update.setId(cart.getId());
                    cartService.updateById(update);
                }
            }
        }
        return ResponseUtil.ok();
    }

    /**
     * 如果是店铺商品，则判断该商品是否属于该店铺，如果是总部商品则判断该商品是否在店铺区域内
     * @param goodsId
     * @param shopId
     * @return
     */
    private boolean hasGoods(Integer goodsId, Integer shopId) {
    	LitemallGoods goods = goodsService.findById(goodsId);
    	if(goods != null && goods.getIsOnSale()){//商品存在且上架
    		if(goods.getType() == 0 ) {
    			//总部商品
    			Integer cityRegionId = getShopRegionId(shopId);
    			LitemallGoodsRegion goodRegion = goodsRegionService.findByGidAndCityId(goodsId, cityRegionId);
    			if(null != goodRegion) {//该商品在店铺区域支持选择
    				return true;
    			}

    		}else if(goods.getType() == 1 && (goods.getShopId() == shopId)) {
    			//店铺商品
    			return true;
    		}

    	}
    	return false;
    }


    public Response rushToPlaceOrder(Integer userId, CartRushToPlaceOrderReqVO reqVO) {
        //先判断一次营业时间
        //当前门店
        LitemallShop shop = litemallShopService.findById(reqVO.getShopId());
        //动态设置门店时区
        dynamicTimeZoneConfiguration.setDynamicTimeZone(shop.getTimezone());
        if (!shopCheckWeeksTime(shop)) {
            return ResponseUtil.fail(8008,"门店已歇业，请营业再来吧");
        }
        //添加到购物车获得id
        Integer cartId = null != reqVO.getCartGoods()?addCartGoods(userId,reqVO):addCartPackage(userId,reqVO);
        CartCheckOutRequest cartCheckOutReq = new CartCheckOutRequest();
        cartCheckOutReq.setCartIds(Arrays.asList(cartId));
        cartCheckOutReq.setAddressId(reqVO.getAddressId());
        cartCheckOutReq.setCouponId(reqVO.getCouponId());
        cartCheckOutReq.setCouponUserId(reqVO.getCouponUserId());
        cartCheckOutReq.setShopId(reqVO.getShopId());
        //结算下单
        return checkOut(userId,cartCheckOutReq);
    }

    private Integer addCartGoods(Integer userId, CartRushToPlaceOrderReqVO reqVO){
        LumiereCartGoods cartGoods = new LumiereCartGoods();
        LitemallGoods goods = goodsService.findById(reqVO.getCartGoods().getGoodsId());
        cartGoods.setGoodsId(goods.getId());
        cartGoods.setPrice(reqVO.getPrice());
        cartGoods.setNumber(reqVO.getCartGoods().getNumber());
        cartGoods.setSpecificationId(reqVO.getCartGoods().getFormulaSpecificationId());
        lumiereCartGoodsService.save(cartGoods);
        //保存商品属性
        List<CartAddGoodsPropertyReqVo> propertyList = reqVO.getCartGoods().getPropertyList();
        if(!CollectionUtils.isEmpty(propertyList)) {
            for (CartAddGoodsPropertyReqVo cartAddPropertyVo : propertyList) {
                LumiereCartGoodsProperty cartGoodsProperty = new LumiereCartGoodsProperty();
                cartGoodsProperty.setCartGoodsId(cartGoods.getId());
                cartGoodsProperty.setGoodsPropertyId(cartAddPropertyVo.getGoodsPropertyId());
                cartGoodsProperty.setName(cartAddPropertyVo.getName());
                cartGoodsProperty.setValue(cartAddPropertyVo.getValue());
                cartGoodsProperty.setCartGoodsId(cartGoods.getId());
                lumiereCartGoodsPropertyService.save(cartGoodsProperty);
            }
        }

        //保存商品原料
        List<CartAddGoodsFormulaSpecificationsDataProportioningReqVO> formulaSpecificationsDataProportioningList = reqVO.getCartGoods().getFormulaSpecificationsDataProportioningList();
        if(CollUtil.isNotEmpty(formulaSpecificationsDataProportioningList)){
            for (CartAddGoodsFormulaSpecificationsDataProportioningReqVO cartAddGoodsFormulaSpecificationsDataProportioningReqVO : formulaSpecificationsDataProportioningList) {
                LumiereCartGoodsFormulaSpecificationsDataProportioning cartGoodsFormulaSpecificationsDataProportioning = new LumiereCartGoodsFormulaSpecificationsDataProportioning();
                cartGoodsFormulaSpecificationsDataProportioning.setCartGoodsId(cartGoods.getId());
                cartGoodsFormulaSpecificationsDataProportioning.setFormulaSpecificationsDataProportioningId(cartAddGoodsFormulaSpecificationsDataProportioningReqVO.getId());
                cartGoodsFormulaSpecificationsDataProportioning.setQuantity(cartAddGoodsFormulaSpecificationsDataProportioningReqVO.getQuantity());
                cartGoodsFormulaSpecificationsDataProportioning.setPrice(cartAddGoodsFormulaSpecificationsDataProportioningReqVO.getPrice());
                cartGoodsFormulaSpecificationsDataProportioning.setGroupName(cartAddGoodsFormulaSpecificationsDataProportioningReqVO.getGroupName());
                lumiereCartGoodsFormulaSpecificationsDataProportioningService.save(cartGoodsFormulaSpecificationsDataProportioning);
            }
        }
        //购物车
        LumiereCart cart = new LumiereCart();
        cart.setUserId(userId);
        cart.setShopId(reqVO.getShopId());
        cart.setCartGoodsId(cartGoods.getId());
        cart.setType(0);
        cart.setPrice(reqVO.getPrice());
        lumiereCartService.save(cart);
        return cart.getId();
    }

    private Integer addCartPackage(Integer userId, CartRushToPlaceOrderReqVO reqVO){
        LumierePackage lumierePackage = lumierePackageService.getById(reqVO.getCartPackage().getPackageId());
        List<Integer> cartGoodsIds = new ArrayList<>();
        //套餐商品
        for (CartRushToPlaceOrderReqVO.CartAddGoodsReqVO cartAddGoodsReqVO : reqVO.getCartPackage().getGoodsList()) {
            LumiereCartGoods cartGoods = new LumiereCartGoods();
            LitemallGoods goods = goodsService.findById(cartAddGoodsReqVO.getGoodsId());
            cartGoods.setGoodsId(goods.getId());
            cartGoods.setPrice(cartAddGoodsReqVO.getPrice());
            cartGoods.setNumber(cartAddGoodsReqVO.getNumber());
            cartGoods.setSpecificationId(cartAddGoodsReqVO.getFormulaSpecificationId());
            lumiereCartGoodsService.save(cartGoods);
            //保存商品属性
            List<CartAddGoodsPropertyReqVo> propertyList = cartAddGoodsReqVO.getPropertyList();
            if(!CollectionUtils.isEmpty(propertyList)) {
                for (CartAddGoodsPropertyReqVo cartAddPropertyVo : propertyList) {
                    LumiereCartGoodsProperty cartGoodsProperty = new LumiereCartGoodsProperty();
                    cartGoodsProperty.setCartGoodsId(cartGoods.getId());
                    cartGoodsProperty.setGoodsPropertyId(cartAddPropertyVo.getGoodsPropertyId());
                    cartGoodsProperty.setName(cartAddPropertyVo.getName());
                    cartGoodsProperty.setValue(cartAddPropertyVo.getValue());
                    cartGoodsProperty.setCartGoodsId(cartGoods.getId());
                    lumiereCartGoodsPropertyService.save(cartGoodsProperty);
                }
            }

            //保存商品原料
            List<CartAddGoodsFormulaSpecificationsDataProportioningReqVO> formulaSpecificationsDataProportioningList = cartAddGoodsReqVO.getFormulaSpecificationsDataProportioningList();
            if(CollUtil.isNotEmpty(formulaSpecificationsDataProportioningList)){
                for (CartAddGoodsFormulaSpecificationsDataProportioningReqVO cartAddGoodsFormulaSpecificationsDataProportioningReqVO : formulaSpecificationsDataProportioningList) {
                    LumiereCartGoodsFormulaSpecificationsDataProportioning cartGoodsFormulaSpecificationsDataProportioning = new LumiereCartGoodsFormulaSpecificationsDataProportioning();
                    cartGoodsFormulaSpecificationsDataProportioning.setCartGoodsId(cartGoods.getId());
                    cartGoodsFormulaSpecificationsDataProportioning.setFormulaSpecificationsDataProportioningId(cartAddGoodsFormulaSpecificationsDataProportioningReqVO.getId());
                    cartGoodsFormulaSpecificationsDataProportioning.setQuantity(cartAddGoodsFormulaSpecificationsDataProportioningReqVO.getQuantity());
                    cartGoodsFormulaSpecificationsDataProportioning.setPrice(cartAddGoodsFormulaSpecificationsDataProportioningReqVO.getPrice());
                    cartGoodsFormulaSpecificationsDataProportioning.setGroupName(cartAddGoodsFormulaSpecificationsDataProportioningReqVO.getGroupName());
                    lumiereCartGoodsFormulaSpecificationsDataProportioningService.save(cartGoodsFormulaSpecificationsDataProportioning);
                }
            }

            cartGoodsIds.add(cartGoods.getId());
        }

        //套餐
        LumiereCartPackage cartPackage =new LumiereCartPackage();
        cartPackage.setNumber(reqVO.getCartPackage().getNumber());
        cartPackage.setPrice(lumierePackage.getAmount());
        cartPackage.setPackageId(lumierePackage.getId());
        cartPackage.setCartGoodsIds(cartGoodsIds);
        lumiereCartPackageService.save(cartPackage);

        //购物车
        LumiereCart cart = new LumiereCart();
        cart.setUserId(userId);
        cart.setShopId(reqVO.getShopId());
        cart.setCartPackageId(cartPackage.getId());
        cart.setType(1);
        cart.setPrice(reqVO.getPrice());
        lumiereCartService.save(cart);
        return cart.getId();
    }
}
